TITLE "decimal.a decimal output demo" ; This file contains ; 1) DECPUT, a recursive subroutine to put numbers out in decimal ; 2) a main program to test the above ; Note that the code here is an optimized version of the file presented ; in the previous lecture. All optimizations are the result of relatively ; local analysis of the code in the previous version. Three basic ; optimizations have been used: ; - 1 - Tracking register use, where a value was already available ; in a register, LOAD instructions were eliminated in favor ; of using the value already available in a register. ; - 2 - After the above, where no remaining LOAD instructions reference ; some local variable, eliminate the STORE instructions to that ; local variable and eliminate the local variable itself. ; - 3 - Where the stack pointer, R2, is decremented after a call and then ; incremented before the next call, eliminate both the decrement ; and increment. This requires that all references to local ; between the eliminated operations be modified so that the ; decrement is built into the memory reference. USE "hawk.macs" USE "monitor.h" S START ; -------------------------------- ; Recursive decimal output routine ; -------------------------------- ; activation record structure RETAD = 0 ; return address REM = 4 ; remainder after division ARSIZE = 8 ; activation record size DECPUT: ; entry point ; on entry, R1 return address ; R2 points to the new AR ; R3 integer parameter STORE R1,R2,RETAD ; save return address in AR ; R3 = param to be divided LIS R4,10 ; R4 = param to divide by LIL R1,DIVU ADDI R2,R2,ARSIZE ; push activation record JSRS R1,R1 ; call divu() to do R3/10 ; quotient stays in R3 STORE R4,R2,REM-ARSIZE; store remainder ; quotient already in R3 TESTR R3 ; compare R3 with zero BLE ENDIF ; if (R3 > 0) { ; R3 = param, quotient JSR R1,DECPUT ; call decput(quotient) ENDIF: ; } LOAD R3,R2,REM-ARSIZE ADDI R3,R3,'0' ; compute remainder + '0' LIL R1,DSPCH JSRS R1,R1 ; call dspch(remainder + '0') ADDI R2,R2,-ARSIZE ; pop activation record LOAD R1,R2,RETAD ; restore return address from AR JUMPS R1 ; actually return ; -------------------------------- ; Main program to test the above ; -------------------------------- EXT UNUSED ; boilerplate start of main program START: LIL R2,UNUSED LIL R1,DSPINI JSRS R1,R1 ; end of boilerplate LIS R8,0 ; initialize loop counter LOOP: ; loop LIS R3,' ' LIL R1,DSPCH JSRS R1,R1 ; call dspch(' ') MOVE R3,R8 JSR R1,DECPUT ; call decput(loop counter) ADD R8,R8,R8 ADDSI R8,1 ; double then increment loop counter CMPI R8,10000 BLT LOOP ; end loop when loop counter > 10,000 LIL R1,EXIT ; boilerplate end of main program JSRS R1,R1 END