;; Main routine .ORIG x3000 MAIN ;; setup stack LD R6, STACKBASE ; set the stack base ADD R5, R6, #0 ; set main's frame pointer LD R0, LZ_AMOUNT ; load param 1 LD R1, LZ_IN ; load param 2 ;; push parameters ADD R6, R6, #-1 ; STR R1, R6, #0 ; push param 2 ADD R6, R6, #-1 ; STR R0, R6, #0 ; push param 1 JSR SUB_FILL_LZ ; call subroutine LDR R0, R6, #0 ; pop return value ADD R6, R6, #1 ; ST R0, RESULT ; store the result ;; cleanup stack ADD R6, R6, #2 ; HALT ;; subroutine: Fill_Leading_Zeroes ;; desc: Takes a number LZ_IN and sets LZ_AMOUNT bits from MSB to LSB to 0 ;; function signature in C might look something like: lc3_word_t fill_LZ(int lz_amount, lc3_word_t lz_in); SUB_FILL_LZ ;; setup stack frame ADD R6, R6, #-1 ; allocate return value ADD R6, R6, #-1 ; STR R7, R6, #0 ; push caller's return address (R7) ADD R6, R6, #-1 ; STR R5, R6, #0 ; push caller's frame pointer (R5) ADD R5, R6, #-1 ; set current frame pointer FP = SP - 1 ADD R6, R6, #-2 ; allocates memory for two local variables (if this function required it) ;; SUB_FILL_LZ does its work... ;; get parameters 1 and 2 LDR R0, R5, #4 ; get LZ_AMOUNT LDR R1, R5, #5 ; get RZ_IN ;; select the appropriate mask LEA R2, MASK16 ; pointer to mask xFFFF BRnz FILL_LZ_DONE ; no work required if LZ_IN <= 0 SELECTMASK ADD R2, R2, #1 ; mask pointer += 1 ADD R0, R0, #-1 ; decrement counter BRp SELECTMASK ; lather, rinse, repeat ;; load and apply the mask LDR R3, R2, #0 ; load the selected mask AND R1, R1, R3 ; apply the selected mask to LZ_IN ;; SUB_FILL_LZ work complete. ;; store result FILL_LZ_DONE STR R1, R5, #3 ; ;; unwind the stack ADD R6, R5, #1 ; reset stack pointer (SP = FP + 1) LDR R5, R6, #0 ; pop caller's frame pointer ADD R6, R6, #1 ; LDR R7, R6, #0 ; pop caller's return address ADD R6, R6, #1 ; RET ;; constants used by FILL_LZ MASK16 .FILL xFFFF MASK15 .FILL x7FFF MASK14 .FILL x3FFF MASK13 .FILL x1FFF MASK12 .FILL x0FFF MASK11 .FILL x07FF MASK10 .FILL x03FF MASK9 .FILL x01FF MASK8 .FILL x00FF MASK7 .FILL x007F MASK6 .FILL x003F MASK5 .FILL x001F MASK4 .FILL x000F MASK3 .FILL x0007 MASK2 .FILL x0003 MASK1 .FILL x0001 MASK0 .FILL x0000 ;; INPUT/OUTPUT VARIABLES STACKBASE .FILL x30FF LZ_AMOUNT .FILL #8 LZ_IN .FILL xFFFF RESULT .BLKW 1 .END