TITLE "MP1 with homebrew putd() by Douglas Jones, fully optimized" USE "hawk.h" USE "monitor.h" ; activation record structure for main() ;RETAD = 0 ; return address ARSIZE = 4 ; code for main() written as a normal subroutine with optimization ; except that hawk monitor lets it use R8 to R15 INT MAIN S MAIN MAIN: ; entry point STORES R1,R2 ADDI R2,R2,ARSIZE ; -- optimization, do this just once LEA R3,HEADING ; -- parameter LIL R1,PUTS JSRS R1,R1 ; puts( heading ) LIS R3,0 ; -- parameter x LIS R4,1 ; -- parameter y LIL R1,PUTAT JSRS R1,R1 ; putat( 0, 1 ) LIS R8,0 ; n = 0 LIS R9,0 ; f = 0 -- always n*(n + 1)/2 LOOP: ; do { LIS R3,' ' ; -- parameter LIL R1,PUTCHAR JSRS R1,R1 ; putchar( ' ' ); MOVE R3,R9 ; -- parameter f, the number to output LIS R4,4 ; -- parameter 4, the field width LIL R1,PUTD JSRS R1,R1 ; putd( n ) ADDSI R8,1 ; n = n + 1 ADD R9,R9,R8 ; f = f + n CMPI R8,19 BLE LOOP ; } until (R8 > 19) ADDI R2,R2,-ARSIZE ; -- optimization, do this just once LOADS R1,R2 JUMPS R1 ; return ; constants used in main() HEADING:ASCII "MP1 by Douglas Jones",0 ALIGN 2 ; --- putd(n) converts n to decimal and outputs it, fully optimized --- ; activation record structure ;RETAD = 0 ; return address DIGIT = 4 ; this digit ARSIZE = 8 ; size of activation record ; code PUTD: ; on entry: R2 stack pointer ; R3 value of n to print ; has permission to wipe out R3-R7 ; returns nothing useful STORES R1,R2 ; -- save RA ADDI R2,R2,ARSIZE ; -- optimized, do this just once ; -- parameter 1 (n already in R3) LIS R5,10 ; -- parameter 2 LIL R1,DIVIDEU JSRS R1,R1 ; digit = n%10; rem = n/10 STORE R4,R2,DIGIT-ARSIZE CMPI R3,0 ; -- rem in R3 already BLE PUTENDF ; if (rem > 0) { ; -- param (already in R3) JSR R1,PUTD ; putd( rem ) -- recursion PUTENDF: ; } LOAD R3,R2,DIGIT-ARSIZE ADDI R3,R3,'0' ; -- param LIL R1,PUTCHAR JSRS R1,R1 ; putchar( digit + '0' ) ADDI R2,R2,-ARSIZE ; -- optimized, do this just once LOADS R1,R2 ; -- restore RA JUMPS R1 ; return END