Assignment 5 Solutions

Part of the homework for 22C:50, Spring 2003
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

From Chapter 6

  1. Rewrite Figure 6.4 so that, when IF or an ELSE is encountered which turns off assembly, the assembler immediately reads forward until it finds the line containing the corresponding ENDIF or ELSE.

    This is a little programming problem; as such, there is no one correct answer, but rather, a family of answers that vary from awful to wonderful. The answer given here is probably somewhere between these extremes, an illustration of a decent answer.

    	procedure line;
    	var level: integer;
    	begin
    	     if lex.this = 'IF' then begin
    		  nextlex {skip IF so operand can be parsed};
    		  if not(operand) then begin
    		       { search for matching else or endif }
    		       level := 1;
    		       repeat
    			    skipline;
    			    if lex.this = 'IF'
    				 then level = level + 1;
    			    if lex.this = 'ENDIF'
    				 then level = level - 1;
    			    if level = 1 AND lex.this = 'ELSE'
    				 then level = level - 1;
    		       until level = 0;
    		  end;
    	     end else if lex.this = 'ELSE' then begin
    		  level := 1;
    		  repeat
    		       skipline;
    		       if lex.this = 'IF' then level = level + 1;
    		       if lex.this = 'ENDIF' then level = level - 1;
    		  until level = 0;
    	     end else if lex.this = 'ENDIF' then begin
    		  /* do nothing */
    	     end else begin
    		  if lex.next = '='
    		       then definition
    		       else statement;
    	     end;
    	     skipline;
    	end {line};
    

  2. Assuming that the macro expansion stack is organized as suggested in Figure 6.13, show the contents of this stack immediately after the first recursive call to TWICE resulting from the expansion of the code in Figure 6.9.

    After the first recursive call to TWICE means after TWICE calls itself for the first time. It only calls itself as a result of the second call given in Figure 6.9.

    		TWICE (TWICE (B 4))
    

    This puts the parameter TWICE (B 4) on the stack, and as we process the body of TWICE, we find that the actual parameter has become a line of text; when we execute this line, we put B 4 on the stack. This gives us the following:

                     n k         n k
                     ______________________________________
           <-push-< |1|m|o|B 4|@|1|x|o|TWICE (B 4)|@| ...
                     ----|-----------|---------------------
                     ^   |_^         |_^
          stack top _|
                     \__________/\__________________/
                       recursive       original
                         call            call
    
               n = the number of parameters.
               k = previous location from which input was being read.
               m = someplace in body of the stored macro text.
               x = value used to indicate text be read from source file.
               @ = end of parameter
    

  3. Write a macro which uses the substring facilities mentioned in the section on extensions to macro assemblers to extract successive decimal digits from a string of decimal digits passed as a parameter.
    Here is a bit of overkill, an answer that actually works under the SMAL assembler on which EAL is based. Spaces have been squeezed out of the listing because SMAL is a bit generous with them:
    SMAL32, rev  6/98.             Fri Feb 28 2003 17:20:59
    
                    1     MACRO PICKAPART (first),(rest)
                    2       IF LEN("first")>2
                    3         LIST +1000  ; turn on listing
                    4         B first
                    5         LIST -1000  ; turn it back off
                    6         PICKAPART (rest):1:1,(rest):2:9999
                    7       ENDIF
                    8     ENDMAC
                    9 
                   10     MACRO DIGITS string
                   11       PICKAPART (string):1:1,(string):2:9999
                   12     ENDMAC
                   13
                   14     DIGITS 0
    +000000: 00    14         B 0
                   15     DIGITS 12
    +000001: 01    15         B 1
    +000002: 02    15         B 2
                   16     DIGITS 123
    +000003: 01    16         B 1
    +000004: 02    16         B 2
    +000005: 03    16         B 3
    

From Chapter 7

  1. If A, B and C are relocatable symbols, and X and Y are absolute symbols, which of the following are legal, and if legal, what is the type of each expression?

    a)(A + X) - Y

    (rel + abs) - abs
    rel - abs
    rel --- it's relocatable

    b)(A + X) - B

    (rel + abs) - rel
    rel - rel
    abs --- it's absolute

    c)(A - B) + (A - C)

    (rel - rel) + (rel - rel)
    abs + abs
    abs -- it's absolute

    d)(A - X) + (B - Y)

    (rel - abs) + (rel - abs)
    rel + rel
    ??? -- it's illegal

    e)(A - B) + (A - X)

    (rel - rel) + (rel - abs)
    abs + rel
    rel -- it's relocatable

  2. If A, B and C are relocatable symbols, the following example could (in principle) be accepted by an assembler, but is normally not allowed:
    		(5 - A)+(B + C)
    
    a) Using Figure 7.6 as a model, find the relocatable value of this expression.
    		 (5 - (A' + R)) +  ((B'+R) + (C'+R))
    		= 5 + -A' + -R  +    B'+ R +  C'+ R
    		= 5 + -A' + -R  +    B'+ R +  C'+ R
    		= 5 + -A' +          B'+ R +  C'
    		= 5 + B' + C' - A' + R
    

    b) Explain why most assemblers will not allow this expression.

    Because it contains a term, (B+C) that is twice relocatable, and another term (5-A) that requires negative relocation.

    c) Rewrite this expression in an equivalent form which would be accepted by most assemblers.

    		= 5 + B' + C' - A' + R
                    = 5 + (B' + R) + (C' - A')
                    = 5 + (B' + R) + ((C' + R) - (A' + R))
                    = 5 + B + (C - A)
                    = 5 + B + C - A