Assignment 4, due Feb 13

Solutions

Part of the homework for CS:2630, Spring 2015
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

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. Background: Suppose the SMAL assembly language only had a B directive, with no support for H or W. You could write a macro to define H in terms of B as follows:
         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.

  2. Background: Assume that the variable i is stored at memory address 65536 (decimal), and you have this program fragment in C (or Python, or Java, or ...):
    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
    

  3. Background: Assemble the hello-world program from chapter 5 of the notes, look at the assembly listing for this program, and then link and run it. (You may need to run it several times, studying the display of the Hawk emulator.)

    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.