This test was intended to probe whether you have understood Practical 20 and the PVM.
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. Suppose Parva and the PVM were extended to provide two simple functions - max() and sqr() - which would you allow you easily to translate code like
int a = max(b, c); int s = sqr(a);
and so on.
(a) What changes would you have to make to the switch statement in the PVM emulator in the Assembler system you have been using to support two additional opcodes that could provide this functionality? [6]
The opcodes can conveniently be applied to a value that is on the top of the stack - how it gets there will be the responsibility of other code. Then it becomes easy. Here are two alternatives. The scond ones manipulate the stack elements directly and are slighlly more efficient:
case PVM.max: // maximum case PVM.max: // maximum tos = pop(); cpu.sp++; sos = pop(); if (mem[cpu.sp - 1] > mem[cpu.sp]) push(tos > sos? tos : sos); mem[cpu.sp] = mem[cpu.sp - 1]; break; break; case PVM.sqr: // square case PVM.sqr: // square tos = pop(); mem[cpu.sp] = mem[cpu.sp] * mem[cpu.sp]; push(tos * tos); break; break;
Occasionally students suggest that one should do a range check, which is impressive:
case PVM.sqr: // square tos = pop(); if (tos != 0 && Math.abs(tos) > maxInt / Math.abs(tos)) ps = badVal; else push(tos * tos); break;
but inevitably I receive some submissions that pop too many values:
case PVM.sqr: // square - this one is WRONG push(pop() * pop()); break;
and, unbelievably, some students confuse squares and square roots!
(b) Would you have to make any other changes to the PVM.java file (that is, besides the main switch statement) to support the extension? Explain your thinking! [4]
We should have to add internal values for max and sqr to the "enumeration" at the start of the file, and we should have to add the corresponding initialisation of the elements of the mnemonic look-up array (at the end of the file). Since these are "zero address" instructions, they do not give rise to further changes in the parts of the file responsible for tracing, assembling or for listing code.
3. From those dim distant maths classes at school you should recall the geometrical theorem of another Great Greek, one Pythagoras, to the effect that if the lengths of the sides of a right angled triangle are denoted by a, b and h (h being the hypotenuse - the side opposite to the right angle) then a2 + b2 = h2.
The following Parva program takes it upon itself to read triples of numbers and determine whether they have this property.
void main () { // Test triples of numbers to see if a right angled triangle could be constructed from them // P.D. Terry, Rhodes University, 2010 int a, b, c; read(a); while (a > 0) { read(b, c); write(a, b, c); if (2 * sqr(max(max(a, b), c)) == sqr(a) + sqr(b) + sqr(c)) writeLine(" form a right angle triangle"); else writeLine(" do not form a right angle triangle"); read(a); } }
(a) Explain the logic behind the rather complicated condition used in the if statement in this program. [4]
The hypotenuse must be the longest side. If the triangle is right angled, the sum a2 + b2 + c2 must represent the sum of the squares of the shorter two sides (whichever they are) plus the square of the longest side (whichever it is), and this sum must be twice the square of the longest side. So all we have to do is find the longest side - which we can do by applying the max() function twice - square it, and double the result, and compare it with the sum of the squares of all of the sides.
(b) Translate this program above into PVM code, making use of your new opcodes, and also of the STL and LDL opcodes you should have implemented during the practical. (Hint: this can be done in about 44 lines, but once you see the patterns it should be easy to write out the code.) [25]
0 DSP 3 offset 0 for a, 1 for b, 2 for c 2 LDA 0 4 INPI read(a); 5 LDL 0 7 LDC 0 9 CGT 10 BZE 66 while (a > 0) { 12 LDA 1 14 INPI read(b); 15 LDA 2 17 INPI read(c); 18 LDL 0 20 PRNI write(a); 21 LDL 1 23 PRNI write(b); 24 LDL 2 26 PRNI write(c); 27 LDC 2 29 LDL 0 31 LDL 1 33 MAX max(a, b) 34 LDL 2 36 MAX max(max(a, b), c) 37 SQR sqr(max(max(a, b), c)) 38 MUL 2 * sqr(max(max(a, b), c)) 39 LDL 0 41 SQR sqr(a) 42 LDL 1 44 SQR sqr(b) 45 ADD 46 LDL 2 sqr(a) + sqr(b) 48 SQR sqr(c) 49 ADD sqr(a) + sqr(b) + sqr(c) 50 CEQ if (2 * sqr(max(max(a, b), c)) == sqr(a) + sqr(b) + sqr(c)) 51 BZE 58 53 PRNS " form a right angle triangle" 55 PRNL writeLine(); 56 BRN 61 else 58 PRNS " do not form a right angle triangle" 60 PRNL writeLine(); 61 LDA 0 63 INPI read(a); 64 BRN 5 } // while 66 HALT System.exit(0);