Assignment 5, due Feb 20Solutions
Part of
the homework for CS:2630, Spring 2015
|
/* mp1test.c */ #include <monitor.h> typedef struct { /* definition of the record type */ char * text; /* pointer to the start of the text string */ int16t x; /* the X coordinate */ int16t y; /* the Y coordinate */ } record; /* linkage to the array of pointers to records in mp1.a */ extern record * array[] main() { int i = 0; while (array[i] != NULL) { putat( array[i]->x, array[i]->y ); puts( array[i]->text ); i = i + 1; } }
You are not expected to know C, but most of the above syntax should look natural. The following notes about pointers in C may help:
In the following, assume that this SMAL declaration for the symbol ARRAY has already been given. It allows the linker to link the symbol ARRAY here to the value it was given in the solution to MP1 with which the test program is linked:
EXT ARRAY
Assume that register R8 is used for the variable i and note that each array element occupies 4 consecutive bytes; that is, the address of array element array[i] is the address of the first element of the array (array[0]) plus 4 times the value of i. Here, we use the notation array as C code, where the corresponging definition in SMAL is ARRAY.
a) Write SMAL Hawk code to compute the address of the array element array[i] in register R9. (0.4 points)
; a stupid but effective solution LIL R9,ARRAY ADD R9,R8,R9 ADD R9,R8,R9 ADD R9,R8,R9 ADD R9,R8,R9; a faster solution LIL R9,ARRAY ADD R10,R8,R8 ; R10 = 2*R8 ADD R10,R10,R10 ; R10 = 2*R10 ADD R9,R9,R10
b) Given that the address of array[i] in register R9, write SMAL Hawk code to load the value of array[i] in R10. The value of array[i] is a pointer to a record. (0.4 points)
LOADS R10,R9
c) Given that the value of array[i] is in R10, write SMAL Hawk code to check if this value is null, and if so, branch to the label DONE. (0.4 points)
; an obvious solution CMPI R10,NULL BEQ DONE; a faster solution that works if NULL is zero TESTR R10 BZS DONE; The fastest solution LOADSCC R10,R9 ; an alternate solution to part b) BZS R10
d) Given that R10 points to one record, that is, R10 holds the value of array[i], write SMAL Hawk code to load the value of the text field of that record (array[i]->text) into R3. That value is a pointer to a piece of text. (0.4 points)
; what should be the obvious solution LOAD R3,R10,TEXT; there are other solutions ADDI R11,R10,TEXT LOADS R3,R11; but there is an optimal solution LOADS R3,R10 ; the text field starts at displacement zero
e) Given that a pointer to the text has already been loaded in R3, write SMAL Hawk code to call the Hawk monitor puts() routine. This completes the coding of puts(array[i]->text). (0.4 points)
; solved in the style of Chapter 5 LOADS R1,PUTS JSRS R1,R1; solved in the general but sub-optimal style of Chapter 6 ADDI R2,R2,ARSIZE LOADS R1,PUTS JSRS R1,R1 ADDI R2,R2,-ARSIZE
Note: This does not go so far as giving the entire mp1test.a because we have not discussed how to work with halfwords on the Hawk machine. That will have to wait until early March.
A question: How does the main program violate the rules for the standard Hawk calling sequence? (0.5 points)
The rules state that the called routine "may destroy the contents of registers R3 through R7, and all are required to leave R8 through R15 unchanged when the routine returns."
Main programs written in the style of Chapter 5 use R8 to R15 without saving and restoring their previous values.
LIL R1,PUTCHAR JSRS R1,R1 ; putchar( ch )
All of the examples in Chapter 6 show the same call looking like this:
ADDI R2,R2,ARSIZE LIL R1,PUTCHAR JSRS R1,R1 ; putchar( ch ) ADDI R2,R2,-ARSIZE
A question: How did Chapter 5 hide the ARSIZE issue from the novice programmer? (0.5 points)
The skeleton of the main program given in Chapter 5 included
ADDI R2,R2,ARSIZEin the boilerplate before the body of the code, and it included
ADDI R2,R2,-ARSIZEin the boilerplate after the body of the code. So long as the code does not reference local variables in RAM (a subject that is not introduced until Chapter 6), the the code will work.