Assignment 4, due Feb 13
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!
MACRO H =x B x & #FF B x >> 8 ENDMAC
Note that the & operator used here in SMAL is defined identically in C, C++, Java, Python and Perl. It means bitwise and. The term is fully defined, with examples, in Wikipedia. Similarly, in all of these languages >> is the bitwise right-shift operator.
a) Give a SMAL definition for the W macro using a sequence of 2 calls to the above H macro. (0.3 points)
MACRO W =x H x & #FFFF H x >> 16 ENDMAC
b) Give a SMAL definition for the W macro using a sequence of 4 B directives. (0.3 points)
First, this might be the easy code to read:MACRO W =x B (x >> 0) & #FF B (x >> 8) & #FF B (x >> 16) & #FF B (x >> 24) & #FF ENDMAC
We didn't really need parentheses, because the SMAL manual says that expressions are evaluated left to right (with no fancy operator precedence rules). Shifting by zero does nothing, and after shifting 24 places, there are only 8 bits left with any meaning. So, we can write this as:MACRO W =x B x & #FF B x >> 8 & #FF B x >> 16 & #FF B x >> 24 ENDMAC
c) Suppose you were programming using SMAL. How could you tell if H and W were defined as built-in directives or defined using the macros discussed above? (Ignore the possibility of more sophisticated macros). There are at least three different things a programmer could observe that, independently, would reveal the answer; for full credit, give any two. (0.4 points)
There is nothing like an experiment to see what is going on:
1 MACRO HH =x 2 B x & #FF 3 B x >> 8 4 ENDMAC 5 6 MACRO WW =x 7 HH x & #FFFF 8 HH x >> 16 9 ENDMAC 10 +00000000: 89ABCDEF 11 W #89ABCDEF 12 +00000004: EF CD AB 89 13 WW #89ABCDEF
This immediately reveals one answer: The built in W directive assembles a single word into the object code, while the homebrew macro version assembles 4 consecutive bytes.
Note added Feb. 20: A very closely related observation: Not only are the listing files different for the built-in and the macro versions, but the object files are also different. Here is the object file with annotations:
R=. W#89ABCDEF -- this came from the built-in W B#EF -- these 4 lines came from the macro WW B#CD B#AB B#89
The observation here about the object file is really exactly the same observation as the previous one about the listing file. As such, it seems fair that a student who listed these two differences should not get full credit. Nonetheless, a student making these two observations should get more credit than a student who just made one or the other.
Now for another experiment. Try to output a value that is out of bounds:
+00000000: 8000 11 H #89ABCDEF value out of bounds ========= 12 +00000002: EF 13 HH #89ABCDEF +00000003: 80 13 B 2309737967 >> 8 value out of bounds ===============
So, we have a second answer: The built-in H directive detects operands that are out of bounds by itself, while the error message for the macro is issued for one of the lines of the macro expansion.
The third answer may be so obvious that you miss it: To use the macro, your source file must either contain the macro definition or it must contain a USE directive for a file containing the macro definition. So, if inspecting the relevant source files doesn't show you a macro definition for H and W, they must be built in.
i = i + 12;
A Problem: Write SMAL Hawk code that carries out the above assignment statement. (1 point)
Note: To do this, you will probably need a sequence of Hawk instructions, including at least one instruction from each of the following categories of instructions: load immediate, add immediate, load, and store. There are several instructions in each of category.
LIL R3,65536 ; load the address of i LOADS R4,R3 ; get the value of i from RAM ADDI R4,R4,12 ; increment by 12 STORES R4,R3 ; put i back in RAM
Note that the comments above belabor what is going on. At the level of this exercise, they are helpful, but for any programmer who understands the pattern being used here, the following comments are more likely to be useful:LIL R3,65536 ; -- address of i LOADS R4,R3 ADDI R4,R4,12 STORES R4,R3 ; i = i + 12
Note that, when you start the Hawk emulator, the first time you hit the r key to run the program, it runs the boot code in our minimal operating system. It stops before running the hello-world program because that program contains the directive S MAIN which tells the emulator to stop when the program counter is equal to the value of the identifier MAIN. Hitting R again will run the hello-world program.
a) When you run the working Hello World program, where in memory does the code actually get put? The first executable instruction of this program is STORES. If you look at the assembly listing for this program when it is about to execute that instruction, that instruction will not be at at location 0, even though the assembly listing shows the location as zero. (0.5 points)
The code starts at location 100016.
b) Look at the assembly listing again, and you will see that every value given in the right side of the listing that differs between what you see in the Hawk emulator display and what you see in the SMAL listing is marked in the listing. What is the mark? (0.5 points)
The assembler puts a + sign in front of every address or value that will be modified by the linker.