Computer Science 3 - 2004 - Test on Prac 20 - Solutions

This should take no longer than 25 minutes and is simply intended to probe whether you have understood the material in the prac. Use your textbook if you think it will help. Answer on the question sheet (3 sides).)

1. I have a memory like my friend Eratosqenes and his sief and cannot remember - remind me of your name (surname) and student number [1]

Pat Terry 63T0844

2. In the prac you were invited to note that sequences like

         LDA   X          and   LDA   Y
         LDV                    <code>
                                STO

occurred so frequently that it was worth introducing special opcodes LDL X and STL Y instead. By now you will recognise something of the Terry perversity - maybe the PVM was originally defined to have LDA, LDV and STO opcodes rather than simply having only LDL and STL opcodes for no other reason than that it makes for lots of fun late at night to add these opcodes to the machine. But maybe not? If you have LDL and STL, could you completely remove LDA, LDV and STO from the opcode list, or would you still need to have them available? Justify your answer. [3]

If every LDV was preceded by an LDA one could get away with using LDL instead of LDA + LDV, and if every other use of LDA was followed by a STO one could get away without LDA. But this is not the case. Consider the following code:

           read(i); list[i] = list[j];

which, even if we use every LDL and STL we can, translates to

           LDA   i
           INPI         ; read(i)
           LDL   list
           LDL   i
           INXA         ; address of list[i]
           LDL   list
           LDL   j
           INXA         ; address of list[j]
           LDV          ; value of list[j]
           STO          ; list[i = list[j]

3. The following algorithm is meant to read a list of numbers and then report on which was the greatest in magnitude. It is not quite right. Make the minimal change needed to correct it. [2]

       void main () {
       // Reads a list of non-zero numbers and reports on which had the
       // greatest magnitude
       // Example: for 1 45 -7 60 -7 0  should report 60
       // Example: for 1 45 -7 60 -70 0  should report -70
       // Ivan Idear, 2004
         int n, max = 0;
         repeat
           read(n);
           if (abs(n) > max) max = n;
         until (n == 0);
         write("largest number was ", max);
       }

All we need is to change the if statement:

           if (abs(n) > abs(max)) max = n;

4. Suppose that the PVM could be extended to incorporate a new opcode PVM.abs for dealing with the abs(n) function in the above code. What addition would be needed to the switch statement in the emulator (as it appears on pages 38 - 39 of the text) to support this new opcode? [3]

      case PVM.abs:
        Push(Math.abs(Pop());
        break;

or even

      case PVM.abs:
        tos = Pop();
        if (tos >= 0) Push(tos); else Push(-tos);
        break;

or even

      case PVM.abs:
        mem[cpu.sp] = Math.abs(mem[cpu.sp]);
        break;

or even

      case PVM.abs:
        if (mem[cpu.sp] < 0) mem[cpu.sp] = -mem[cpu.sp];
        break;   

5. Show how the corrected algorithm could be coded into PVM code, making use of PVM.abs. [9]

Hint: you will be able to write a shorter translation if you make use of the LDL N and STL N opcodes mentioned in question 2, so feel free to do so.

     0  DSP   2    ; variable 0 is n, variable 1 is max     0  DSP   2    ; variable 0 is n, variable 1 is max
     2  LDA   1                                             2  LDC   0
     4  LDC   0                                             4  STL   1    ; max = 0;
     6  STO        ; max = 0;                               6  LDA   0    ; repeat
     7  LDA   0    ; repeat                                 8  INPI       ;   read(n);
     9  INPI       ;   read(n);                             9  LDL   0
    10  LDA   0                                            11  ABS        ;   // abs(n)
    12  LDV                                                12  LDL   1
    13  ABS        ;   // abs(n)                           14  ABS        ;   // abs(max)
    14  LDA   1                                            15  CGT
    16  LDV                                                16  BZE   22   ;   if (abs(n) > abs(max)
    17  ABS        ;   // abs(max)                         18  LDL   0
    18  CGT                                                20  STL   1    ;     max = n;
    19  BZE   27   ;   if (abs(n) > abs(max)               22  LDL   0
    21  LDA   1                                            24  LDC   0
    23  LDA   0                                            26  CEQ
    25  LDV                                                27  BZE   6    ; until (n == 0;
    26  STO        ;     max = n;                          29  PRNS  "largest number was "
    27  LDA   0                                            31  LDL   1
    29  LDV                                                33  PRNI       ; write(max)
    30  LDC   0                                            34  HALT       ; exit
    32  CEQ
    33  BZE   7    ; until (n == 0;
    35  PRNS  "largest number was "
    37  LDA   1
    39  LDV
    40  PRNI       ; write(max)
    41  HALT       ; exit

6. Briefly indicate where, if anywhere, you would have to make other changes to the PVM.java file to handle this new opcode [2].

We should have to add an internal value for abs to the "enumeration" at the start of the file, and we should have to add the corresponding initialisation of the element of the mnemonic look-up array (at the end of the file). Since this is a "zero address" instruction, it does not give rise to further changes in the parts of the file responsible for tracing or for listing code.

7. Suppose you could not introduce or use the PVM.abs opcode. How would you then code an algorithm like the following in PVM code, using only one PVM.prni opcode? [5]

       void main () {
         int i;
         read(i);
         write(abs(i));
       }

     0  DSP   1    ; variable 0 is i              0  DSP   1    ; variable 0 is i
     2  LDA   0                                   2  LDA   0
     4  INPI       ; read(i)                      4  INPI       ; read(i)
     5  LDA   0                                   5  LDL   0
     7  LDV                                       7  LDC   0
     8  LDC   0                                   9  CGT
    10  CGT                                      10  BZE   16   ; if (i > 0)
    11  BZE   18   ; if (i > 0)                  12  LDL   0    ;   i on tos
    13  LDA   0                                  14  BRN   19
    15  LDV        ;   i on tos                  16  LDL   0    ;   i on tos
    16  BRN   22                                 18  NEG        ;  -i on tos
    18  LDA   0    ;   i on tos                  19  PRNI       ; write(abs(i));
    20  LDV                                      20  HALT       ; exit
    21  NEG        ;  -i on tos
    22  PRNI       ; write(abs(i));
    23  HALT       ; exit


Home  © P.D. Terry