Homework 3 Solutions

22C:18, Summer 1997

Douglas W. Jones
  1. This solution preserves the original C code verbatim as comments.
    	TITLE	HW3 Problem 1 program
    	USE	"/group/class/22c018/hawk.macs"
    	USE	"/group/class/22c018/hawk.system"
    	S	main
    main:
    	LOAD	R2,PSTACK
    	CALL	DSPINI
    	LIS	R8,50	; int t = 50
    loop:
    	CMPI	R8,1	; while (t > 1) {
    	BLE	endloop
    	LIS	R9,1
    	AND	R9,R8	;     if (t & 1) {
    	BZS	else
    	ADDSL	R8,R8,1 ;         t = (t * 3) + 1;
    	ADDSI	R8,1
    	BR	endif
    else:			;     } else {
    	SR	R8,1	;         t = t / 2;
    endif:			;     }
    	MOVE	R3,R8
    	LIS	R9,8
    	CALL	DSPDEC	;     printf("%d ",t);
    	BR	loop	; }
    	LEA	R3,stop
    	CALL	DSPST	; printf("STOP");
    	CLR	R1
    	JUMPS	R1	; --- really stop
    stop:	ASCII	"STOP",0
    

  2. To detect overflows, we modify the above as follows. New lines are marked to stand out from the old ones!
    	TITLE	HW3 Problem 2 program
    	USE	"/group/class/22c018/hawk.macs"
    	USE	"/group/class/22c018/hawk.system"
    	S	main
    main:
    	LOAD	R2,PSTACK
    	CALL	DSPINI
    	LIS	R8,50	; int t = 50
    loop:
    	CMPI	R8,1	; while (t > 1) {
    	BLE	endloop
    	LIS	R9,1
    	AND	R9,R8	;     if (t & 1) {
    	BZS	else
    	ADDSL	R8,R8,1 ;         t = (t * 3) + 1;
    	BVS	error	;	  ====== detect overflow
    	ADDSI	R8,1
    	BVS	error	;	  ====== detect overflow
    	BR	endif
    else:			;     } else {
    	SR	R8,1	;         t = t / 2;
    endif:			;     }
    	MOVE	R3,R8
    	LIS	R9,8
    	CALL	DSPDEC	;     printf("%d ",t);
    	BR	loop	; }
    	LEA	R3,stop
    	CALL	DSPST	; printf("STOP");
    	CLR	R1
    	JUMPS	R1	; --- really stop
    error:			; ====== on overflow, come here
    	LEA	R3,ermsg; ======
    	CALL	DSPST	; ====== printf("ERR");
    	CLR	R1	; ======
    	JUMPS	R1	; ====== --- really stop
    stop:	ASCII	"STOP",0
    ermsg:	ASCII	"ERR!",0 ;=====
    

  3. Part A: The following C declaration of an array of two-element records translate to SMAL Hawk assembly language as shown:
    	struct rec {
    		long int x;
    		char y,z;
    	} z[4];
    
    	; an array of 4 recs
    		COMMON	zd,4*recs
    	zp:	W	zd
    
    	; fields of the structure rec
    	x =	0	; an integer (4 bytes)
    	y = 	4	; a character (1 byte)
    	z = 	5	; a character (1 byte)
    	recs =  8	; size of a rec (2 words)
    
    Part B: In terms of the above declarations, the nonsense code fragment can be translated as:
    		LIS	R8,0	; for (i=0; i < 3; i++) {
    	loop:	CMPI	R8,3
    		BGE	endloop
    
    		LOAD	R9,zp		; R9 = z
    		MOVE	R10,R8
    		ADDS	R10,R9,3	; R10 = &z[i]
    		MOVE	R11,R8
    		ADDSI	R11,1
    		ADDS	R11,R9,3	; R11 = &z[i+1]
    		LEA	R12,R11,y	; R12 = &z[i+1].y
    		LOADS	R13,R12
    		EXTB	R13,R13,R12	; R13 = z[i+1].y
    		LEA	R14,R11,z	; R14 = &z[i+1].z
    		LOADS	R15,R14
    		EXTB	R15,R15,R14	; R15 = z[i+1].z
    		ADD	R14,R14,R15	; R14 = z[i+1].y + z[i+1].z
    		STORE	R14,R10,x	; z[i].x = R14
    
    		ADDSI	R8,1
    		BR	loop	; }
    	endloop:
    
    This code is deliberately very stupid, which makes it considerably longer than necessary. It takes no advantage that fields y and z of each array element are in the same word and it takes no advantage of the fact that knowing the address of one array element allows trivial computation of the address of the next. This stupidity allows the easy identification of the relationship between each machine instruction and a specific part of the high level language statements
  4. Here is an appropriately documented HAWK macro to load a halfword from memory, with no alignment constraints: assuming that the addressed halfword is aligned properly:
    MACRO	LOADHSNA =dst,=x
      ; LOAD Halfword Short NonAligned, in 8 instructions
      ADDSI	x,1
      LOADS	R15,x
      EXTB	R15,R15,x	; get second byte of halfword
      ADDSI	x,-1
      LOADS	dst,x
      EXTB	dst,dst,x	; get first byte of halfword
      TRUNC dst,8		; truncate first byte
      ADDSL dst,R15,8	; shove second byte over and merge
    ENDMAC
    
  5. The code in question assembles to the following:
                                 1          USE "hawk.macs"
                                 2
                                 3          MACRO   LOADHS  =dst,=x
                                 4            LOADS dst,x
                                 5            EXTH  dst,dst,x
                                 6          ENDMAC
                                 7
                                 8          LIL     R5,#00012345
    +000000: E501  2345          9  looptop:
                                10          LOADHS  R6,R5
    +000004: F665  4665         11          BZS     loopexit
    +000008: BA02               12          ADDSI   R5,2
    +00000A: 1552               13          BR      looptop
    +00000C: B8FB               14  loopexit:
                                15
                                16          END