# Assignment 9, due Apr 4

## Solutions

On every assignment, write your name legibly as it appears on your University ID card! Homework is due on paper at the start of class on the day indicated (usually Friday). Exceptions will be made only by advance arrangement (excepting "acts of God"). Late work must be turned in to the TA's mailbox (ask the CS receptionist in 14 MLH for help). Never push homework under someone's door!

1. A small problem: Suppose that R3 and R4 contains the 64-bit value a and R5 and R6 contain another 64-bit value b. (the least significant halves are in R3 and R5). Write Hawk code to perform this assignment:
a = a + b;

This only takes a few instructions. (0.5 points)

2. Background: Suppose that R3 contains a 2's complement value and you perform the following:
SR      R3,4

You might say you have just divided R3 by 16, and for many purposes, you did. On the other hand, the result may not conform to your intuitive expectation for division by 16.

a) Compare the result of computing (-20)/16 following the rules you learned in elementary school with the result you get with the above code. (0.2 points)

(-20)/16 by hand is -(20/16) = -1

(-20)/16 by shifting is (-20)>>4 = -101002>>4 = 1111011002>>4 = 111102>>4 = -2

b) Explain the difference. (Hint, it has to do with the remainder after division.)

Doing it by hand, we conventionally truncate the result toward zero, converting -1.25 to -1. In this case, the remainder after division is -4.

Shifting truncates toward the next lower value, converting -1.25 to -2. In this case, the remainder after division is +12.

(0.3 points)

3. Background: Consider this little subroutine, packaged as a file called sub.a that is designed to be assembled separately from its caller:
TITLE   "sub.a, a subroutine"
INT     SUB
SUB:    ; returns R3 = sum i from i=min to max (constant bounds)
; uses    R4 = i
LIS     R4,MIN          ; i = min
LIS     R3,0            ; sum = 0
LOOP:
CMPI    R4,MAX
BGT     QUIT            ; while (i <= max) {
;       ----- cut here -----
ADD     R3,R3,R4        ;   sum = sum + i
BR      LOOP
QUIT:                           ; }
JUMPS   R1
MIN     =       5
MAX     =       10

A problem: Divide this subroutine into two separately assembled files, one containing all the code above the line saying "cut here" and one containing all the code below that line. The first half should continue to be stored in the file sub.a while the second half goes in a new file, sub2.a. Your goal is to make the bare minimum changes necessitated by this division, while retaining as much as possible of the original logic and structure of the program. That is, MIN and MAX should still be defined in the same place, which is now in sub2, and the return from the subroutine is now from near the end of sub2.a even though the entry point to the subroutine is in a different file, sub.a. (1.0 points)

Note: This is not a recommended programming style! This problem is really about understanding the limitations that apply to the use of external symbols. There are places where they do not work, and as a consequence, you have to substitute less efficient and possibly less readable code for several of the simple instructions above.

Your answer should be in the form of blocks of code, one representing each file, where the code in each file has a TITLE directive naming that file. Obviously, you will have to add INT LOOP and EXT QUIT to sub.a, and you will have to add EXT LOOP and INT QUIT to sub2.a, but there is more work to do because of the machine instructions that do not work with external symbols.

Comments in the following code indicate and explain changes

TITLE   "sub.a, the first half of a subroutine"
INT     SUB

SUB:    ; returns R3 = sum i from i=min to max (constant bounds)
; uses    R4 = i
LIS     R4,MIN          ; i = min
LIS     R3,0            ; sum = 0
LOOP:
LIS     R5,MAX          ; -- added: CMP R4,MAX is illegal
CMPI    R4,R5           ; -- changed
BGT     QUITX           ; while (i <= max) { -- changed: can't BR QUIT
JUMPS   R5              ;   -- added -- can't fall through to part b

QUITX:  LIL     R5,QUIT         ; -- added
;       ----- cut here -----

TITLE   "sub2.a, second half of subroutine
;       ----- cut here -----

CONTINUE:                       ;   -- added -- can't fall through to here
ADD     R3,R3,R4        ;   sum = sum + i
JUMPS   R5              ;   -- changed -- can't BR LOOP
QUIT:                           ; }
JUMPS   R1
MIN     =       5
MAX     =       10

A number of students tried using a COMMON block to share access to MIN and MAX between the two parts of the program. As far as we could tell, none of them use it correctly.

4. Background: Consider the following description of a stream class.
; stream.h -- standard interface to all streams

; all stream objects have the following core structure
STRCLASS=       0       ; pointer to stream class descriptor
;                       ; each distinct subclass may add fields here
;                       ; subclasses must provide the object size

; each subclass must provide a class descriptor that conforms
; to the following structure:
PUT     =       0       ; pointer to the put method
; expects R3 = pointer to stream object
;         R4 = character to put

GET     =       4       ; pointer to the get method
; expects R3 = pointer to stream object
; returns R3 = one character from the stream

CLOSE   =       8       ; pointer to the close method
; expects R3 = pointer to stream object

A Problem Assume that the global variable STDOUT (an external symbol) points to a stream object, write code to put the character "a" out to that stream. (1.0 points)

Here is a pedantic solution, avoiding optimization:

LIL     R3,STDOUT
LOADS   R3,R3           ; -- parameter R3, the value of STDOUT
LIS     R4,'a'          ; -- parameter R4, 'a'
LOAD    R1,R3,STRCLASS  ; -- get pointer to class descriptor
LOAD    R1,R1,PUT       ; -- get pointer to method from descriptor
JSRS    R1,R1           ; stdout.put('a')