Assignment 9, due Apr 4Solutions
Part of
the homework for 22C:60 (CS:2630), Spring 2014
|
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!
a = a + b;
ADD R3,R3,R5 ADDC R4,R6
This only takes a few instructions. (0.5 points)
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.)
(0.3 points)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.
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 INT LOOP ; -- added EXT MIN ; -- added EXT MAX ; -- added EXT QUIT ; -- added EXT CONTINUE ; -- added 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 LIL R5,CONTINUE ; -- added JUMPS R5 ; -- added -- can't fall through to part b QUITX: LIL R5,QUIT ; -- added JUMPS R5 ; -- added ; ----- cut here ----- TITLE "sub2.a, second half of subroutine ; ----- cut here ----- INT CONTINUE ; -- added INT QUIT ; -- added EXT SUB ; -- added EXT LOOP ; -- added CONTINUE: ; -- added -- can't fall through to here ADD R3,R3,R4 ; sum = sum + i LIL R5,LOOP ; -- added JUMPS R5 ; -- changed -- can't BR LOOP QUIT: ; } JUMPS R1 MIN = 5 MAX = 10A 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.
; 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' ADDI R2,R2,ARSIZE 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') ADDI R2,R2,-ARSIZEHere is a solution that replaces LOAD rd,rx,0 with LOADS rd,rx to make it faster:
LIL R3,STDOUT LOADS R3,R3 ; -- parameter R3, the value of STDOUT LIS R4,'a' ; -- parameter R4, 'a' ADDI R2,R2,ARSIZE LOADS R1,R3 ; -- get pointer to class descriptor LOADS R1,R1 ; -- get pointer to method from descriptor JSRS R1,R1 ; stdout.put('a') ADDI R2,R2,-ARSIZE