.orig x3000 ; program calls sum, a recursive subroutine that ; calculates the sum of the ints 0+1+...+n lea r6, stackbase ; r6 is the stack pointer and r0, r0, #0 add r0, r0, #3 ; pass 3 as arg to sum (0+1+2+3=?) jsr push jsr sum halt ; sum 0+1+2+3=6 should be in R1 ; sum is a recursive subroutine that calculates the sum 0+1+2+...+n ; where n is passed to the subroutine on the stack ; sum returns the sum in R1 sum add r0, r7, #0 ; copy return address to R0 jsr push ; and push on the stack ldr r0, r6, 1 ; grab argument from stack brnp cont ; argument = 0? and r1, r1, #0 ; yes, base case, return sum=0 brnzp done cont add r0, r0, #-1 ; no, argument != 0, call sum(n-1) jsr push ; put new argument on stack jsr sum ; make recursive call ldr r0, r6, #1 ; pick up argument to add to sum add r1, r1, r0 ; (it's on the stack) done jsr pop ; pop return address to prepare to return ; to previous level st r0, savr7 ; save temporarily (because r7 needs to be used ; for next JSR) jsr pop ; take argument off stack (this is the argument ; that has most recently been added to the sum) ld r7, savr7 ; restore return address ret savr7 .fill #0 ; place to save return address ; note that these implementations for push and pop do not ; check for overflow or underflow ; stack pointer is in R6 ; item to be push'd or pop'd is in R0 push add r6, r6, #-1 str r0, r6, #0 ret pop ldr r0, r6, #0 add r6, r6, #1 ret stackmax .blkw #20 ; area to hold items on the stack stackbase .fill x0000 ; stack address .end