;----------------------------------------------------------------- ; EX74.ASM PROCEDURE CALL TO void DELAY(unsigned N) ; Parameter Passing via the Stack ; ; C.P. Diduch 2001 ; ; The main program toggles the state of an LED every T ms. The ; procedure, void DELAY(unsigned N), is called to implement ; a software delay of N milliseconds. The parameter, N, is passed ; (as a local variable) on the stack. ; ; Author(s): ; Signature(s): Date: ;----------------------------------------------------------------- ; PROGRAM CONSTANTS ; .EQU TS 50 ; #define TS 50 ; ; ; STACK and VARIABLES ; ; ; .ORG 0x0000 ; "assign following to RAM" .DS 5 ; "reserve space for stack" TOS: .DS 1 ; ; ;----------------------------------------------------------------- ; MAIN PROGRAM ; void main(void) { ; .ORG 0x8000 ; "assign the following to ROM" ; ADDL SP, NULL, TOS ; "initialize stack pointer" XOR R2, R2, R2 ; X = 0 ; // Reg. var. in R2. ; do { M0: STOREP 0x0002, R2 ; outport(0x0002, X) ; ADDL R0, NULL, 1000 ; SUBL SP, SP, 1 ; "T=1000 is pushed on the stack" DSTOREM (SP), R0 ; CALL DELAY, RA ; DELAY(1000) ; XORL R2, R2, 0x0001 ; X = X ^ 0x0001 ; JMP M0 ; } ; } ;----------------------------------------------------------------- ; PROCEDURE void DELAY(unsigned N) ; ; Implements a software delay of N milliseconds by invoking a ; delay of 1 ms, N times. The 1 ms delay is implemented by ; decrementing register R1 from TS to 0. TS is a constant chosen ; such that it takes 1 ms to decrement R1 to 0. Parameter, N, is ; passed on the stack (as a local variaable). ; ; Registers affected : R0, R1, FL. ; Calls : no procedures. ; Called by : main(). ; Stack depth : 2 words. ; ; Call/linkage sequence : T: .DW 5 ; ; LOADM R1, T ; ; SUBL SP, SP, 1 ; ; DSTORE (SP), R1 ; "push T" ; CALL RA, DELAY ; DELAY(T) ; ; The stack frame : Return Address (push RA) ; Parameter T (push T) ; DELAY: ; void DELAY(unsigned N) { SUBL SP, SP, 1 ; DSTOREM (SP), RA ; "save status" : push RA DLOADM R0, 1(SP) ; "copy N from stack into R0" ; D0: SUBL NULL, R0, 0 ; while (N != 0) { JMPZ D3 ; ADDL R1, NULL, TS ; R1 = TS ; ; D1: SUBL NULL, R1, 0 ; while (R1 != 0) { JMPZ D2 ; SUBL R1, R1, 1 ; R1 = R1 - 1 ; JMP D1 ; } ; D2: SUBL R0, R0, 1 ; N = N - 1 ; JMP D0 ; } ; D3: DLOADM RA, (SP) ; "restore status" : pop RA ADDL SP, SP, 1 ; ADDL SP, SP, 1 ; "clean up stack" DJMP (RA) ; }