Homework 4 Solutions

22C:18, Summer 1997

Douglas W. Jones
  1. Here is an appropriately commented SMAL Hawk assembly language program that is very close in its logic to the original C program. Since this example demonstrates separate assembly, it is made up of two source files:
    	TITLE	funct.a, homework 4 problem 1 
    	USE	"/group/class/22c018/hawk.macs"
    
    	INT	FUNCT
    ; -------------------
    ; Activation record structure, indexed from R2
    ;RA =	0	; return address
    X =	4	; saved parameter
    A =	8	; local variable
    AR =	12	; activation record size
    
    FUNCT:
    		; on entry, R3 = parameter X
    		; on exit, R3 = result
    		; uses R3
    	CMPI	R3,2	   ; see if X <= 2
    	BLE	FUNQT	   ;   quit and return X if so
    
    	STORES	R1,R2	   ; save RA
    	STORE	R3,R2,X	   ; save X
    
    	ADDSI	R3,-1	   ; set up parameter for call
    	ADDI	R2,AR
    	JSR	R1,FUNCT   ; recursive call FUNCT(X-1)
    	STORE	R3,R2,A-AR ; save result as A
    	LOAD	R3,R2,X-AR ; recorver X for next call
    	ADDSI	R3,-3	   ; set up parameter for call
    	JSR	R1,FUNCT   ; recursive call FUNCT(X-3)
    	SUBI	R2,AR
    	LOAD	R1,R2,A	   ; recover A from first call
    	ADD	R3,R3,R1   ; setup to return A+FUNCT(X-3)
    
    	LOADS	R1,R2	   ; recover RA
    FUNQT:
    	JUMPS	R1	   ; return!
    
    	END
    	
    	
    	TITLE	main.a, homework 4 problem 1 
    	USE	"/group/class/22c018/hawk.macs"
    	USE	"/group/class/22c018/hawk.system"
    
    	S	MAIN
    
    	EXT	FUNCT
    PFUNCT:	W	FUNCT
    
    ; -------------------
    
    MAIN:
    	LOADS	R2,PSTACK
    	CALL	DSPINI
    
    	LIS	R8,1	   ; initialize loop counter I
    LP:
    	MOVE	R3,R8	   ; setup parameter for call
    	CALL	FUNCT	   ; call FUNCT(I)
    	LOADI	R4,8	   ; setup parameter for call
    	CALL	DSPDEC	   ; call DSPDEC(FUNCT(I),8)
    	ADDSI	R8,1	   ; increment I
    	CMPI	R8,8	   ; test for end of loop
    	BLT	LP	   ;   continue loop if I < 8
    
    	LIS	R1,0
    	JUMPS	R1	   ; exit gracefully
    
    	END
    

  2. 1/1 - not possible (result >= 1)
    1/2 - .100000000000...
    1/3 - .010101010101...
    1/4 - .010000000000...
    1/5 - .001100110011...
    1/6 - .001010101010...
    1/7 - .001001001001...
    1/8 - .001000000000...
    1/9 - .000111000111...
    1/10 - .000110011001...

  3. Consider the following simple (but typical) binary floating point format.
             _ _ _ _ _ _ _ _ _ _ _
    	|_|_|_|_|_|_|_|_|_|_|_|
            | |       |           |
             s   exp    mantissa
    
    For all integer x between 1 and 10, here are the closest approximations to the values of 1/x, shown in binary in this system, with errors given:
    1/1 - 0 1001 100000 = 1.0000 no error
    1/2 - 0 1000 100000 = 0.5000 no error
    1/3 - 0 0111 101011 = 0.3359 error .00260
    1/4 - 0 0111 100000 = 0.2500 no error
    1/5 - 0 0110 110011 = 0.1992 error .00078
    1/6 - 0 0110 101011 = 0.1680 error .00130
    1/7 - 0 0110 100101 = 0.1445 error .00167
    1/8 - 0 0110 100000 = 0.1250 no error
    1/9 - 0 0101 111001 = 0.1113 error .00022
    1/10 - 0 0101 110011 = 0.0996 error .00039

  4. Here is a fast version of strcpy():
    ; --------------
    STRCPY:
    	; on entry R3 = destination address
    	; on entry R4 = source address
    	; uses R3,R4,R5,R6,R7
    
    ; part 1, copy odd stuff from the first word!
    	LOADSCC	R5,R4	; get the word (and see if it has a null)
    	BCS	STRLST	;   this is the last word!
    STRSTA:
    	MOVE	R6,R4	; see if we're on a word boundary
    	TRUNC	R6,2
    	BZS	STRBOD	;   if so, we have first word of body
    	EXTB	R6,R5,R4; get one byte
    	LOADS	R7,R3
    	STUFFB	R7,R6,R3; stuff that byte into place
    	STORES	R7,R3
    	ADDSI	R3,1	; bump pointers
    	ADDSI	R4,1
    	BR	STRSTA	;   continue copying first bytes
    
    ; part 2, copy string body
    STRBOD:
    	MOVE	R6,R3	; see if destination is aligned
    	TRUNC	R6,2
    	BZR	STRLST	; we're not aligned!  Do it slow!
    STRBLP:
    	STORES	R5,R3	; save the word
    	ADDSI	R3,4	; bump the pointers
    	ADDSI	R4,4
    	LOADSCC	R5,R4	; get the word (and see if it has a null)
    	BCR	STRBLO	;   if not the last word, go onward!
    
    ; part 3, copy remainder
    STRLST:
    	EXTB	R6,R5,R4; get next byte
    	BZS	STRQT	;   quit if byte is null
    	LOADS   R7,R3
    	STUFFB  R7,R6,R3; stuff that byte into place
    	STORES  R7,R3   
    	ADDSI   R3,1    ; bump pointers
    	ADDSI   R4,1
    	LOADS	R5,R4	; get next word
    	BR	STRLST
    
    ; part 4, wrapup
    STRQT:
    	LOADS   R7,R3
    	STUFFB  R7,R6,R3; stuff null into place
    	STORES  R7,R3   
    	JUMPS	R1	; return
    

  5. Here is a routine to convert BCD numbers to printable ASCII:
    ; -------------
    BCDTOA:
    	; on entry, R3 = BCD number
    	; on entry, R4 = address of 8 character string
    	; on exit, R3 = address of string (as in C library)
    	; uses R5,R6,R7
    
    	LEA	R5,R4,8	; compute address of end of string
    
    ; part 1 -- put digits into end of string
    BCDLP:
    	MOVE	R6,R3	; get a BCD digit
    	TRUNC	R6,4
    	ADDI	R6,'0'	; make it into ASCII
    	ADDSI	R5,-1	; push pointer onward
    	LOADS	R7,R5
    	STUFFB	R7,R6,R5; stuff character into string
    	STORES	R7,R5
    	SRU	R3,4	; shift next digit into place
    	BZR	BCDLP	;   if more digits, convert them
    	
    ; part 2 -- put blanks before the digits
    	LIS	R6,' '	; the blank!
    BCDBL:
    	CMP	R5,R4	; see if more space in string
    	BEQ	BCDQT	;   if not, quit
    	ADDSI   R5,-1   ; push pointer onward
    	LOADS   R7,R5
    	STUFFB  R7,R6,R5; stuff blank into string
    	STORES  R7,R5
    	BR	BCDBL	; iterate
    
    BCDQT:
    	MOVE	R4,R3	; put pointer in place for return
    	JUMPS	R1	; return