TITLE "Fibonacci with homebrew putd() by Douglas Jones" 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, optimized ; 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 LOOP: ; do { LIS R3,' ' ; -- parameter LIL R1,PUTCHAR JSRS R1,R1 ; putchar( ' ' ); MOVE R3,R8 ; -- parameter n JSR R1,FIB ; f = fib( n ) ; -- parameter f, already in R3 LIL R1,PUTD JSRS R1,R1 ; putd( f ) ADDSI R8,1 ; n = n + 1 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 "Fibonacci by Douglas Jones",0 ALIGN 2 ; --- fib(n) outputs the nth Fibonacci number, optimized --- ; activation record structure ;RETAD = 0 ; return address N = 4 ; param F = 8 ; function value ARSIZE = 12 ; size of activation record ; code FIB: ; expects R3 = n ; returns R3 = f(n) = f(n-1) + f(n-2) unless n < 2 STORES R1,R2 ADDI R2,R2,ARSIZE ; -- done just once STORE R3,R2,N-ARSIZE ; f = n CMPI R3,1 BLE FIBENDF ; if (n > 1) { ADDSI R3,-1 ; -- param n-1, n already in R3 JSR R1,FIB ; f = fib(n - 1) STORE R3,R2,F-ARSIZE LOAD R3,R2,N-ARSIZE ADDSI R3,-2 ; -- param n-2, JSR R1,FIB ; g = fib(n - 2) LOAD R4,R2,F-ARSIZE ADD R3,R3,R4 ; f = f + g FIBENDF: ; } ADDI R2,R2,-ARSIZE ; -- done just once LOADS R1,R2 JUMPS R1 ; return f, already in R3 ; --- putd(n) converts n to decimal and outputs it --- ; 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