ECE 447: Lecture 15 Stack Operations
ECE 447: Stack after a function call SP after a function call RTNH SP before a function call RTNL MAX_ADDRESS
ECE 447: Stack Operations Subroutine call and return from subroutine N Z V C BSR REL – – – – JSR DIR, EXT, IND – – – – RTS INH – – – –
ECE 447: Stack after an interrupt call SP after an interrupt CC B A IXH IXL IYH IYL RTNH SP before an interrupt RTNL MAX_ADDRESS
Interrupt related instructions and return from an interrupt ECE 447: Stack Operations Interrupt related instructions and return from an interrupt N Z V C SWI INH – – – – WAI INH – – – – RTI INH – – – –
ECE 447: Stack Operations Push and pull N Z V C PSH [A, B] PSH [X, Y] PUL [A, B] PUL [X, Y] INH – – – – Initialize and store stack pointer N Z V C LDS IMM, DIR, EXT, IND 0 – STS DIR, EXT, IND 0 –
ECE 447: Stack Operations Jump Stack pointer manipulation JMP DIR, EXT, IND – – – – Stack pointer manipulation DES INH – – – – INS INH – – – – TS [X, Y] INH – – – – T [X, Y] S INH – – – –
Using the stack - Entering a function with a fixed number of arguments and local variables caller function called function D SP var_1 arg_1 IX Local variables ... or IX D DES or PSHX var_M arg_1H arg_1L reg_1 reg_1 ... ... Saved registers PSH reg_L TSX reg_L JSR or BSR RTNH RTNH RTNH Return address RTNL RTNL RTNL arg_2 arg_2 arg_2 arg_N ... arg_2 arg_N ... PSH ... ... Function arguments SP arg_N arg_N
ECE447: Exiting a function: “called-cleanup” method caller function called function D SP ret or IX var_1 IX D Local variables ... retH retL var_M reg_1 reg_1 INS or PUL ... ... Saved registers PUL reg_L reg_L PULY INS RTNH RTNH RTNH Return address RTNL RTNL RTNL arg_2 arg_2 arg_N ... arg_2 arg_N ... ... Function arguments JMP 0,Y SP arg_N
Using the stack - Entering a function with a variable number of arguments caller function called function SP IX var_1 Local variables ... DES or PSHX var_M reg_1 reg_1 ... ... Saved registers PSH reg_L TSX reg_L JSR or BSR RTNH RTNH RTNH Return address RTNL RTNL RTNL arg_1 arg_1 arg_1 arg_N ... arg_1 arg_N ... PSH ... ... Function arguments SP arg_N arg_N
Using the stack - Exiting a function “caller-cleanup” convention called function D SP ret IX var_1 Local variables ... or IX D TXS var_M retH retL reg_1 reg_1 INS or PULX ... ... Saved registers PUL reg_L reg_L RTNH RTNH RTNH Return address RTNL RTNL RTNL RTS arg_1 arg_1 arg_1 arg_N ... arg_1 arg_N ... PULz ... ... Function arguments SP arg_N arg_N
In this example, long = 32bits main.c /* C version of main function */ #include <stdio.h> extern long multadd(unsigned int a, unsigned char b, long c, long *pm); long product, sum; void main(void) { sum = multadd(258, 17, 32L, &product); } In this example, long = 32bits
multadd.c /* C version of the multadd function */ long multadd(unsigned int a, unsigned char b, long c, long *pm) /* this function returns a*b + c and writes a*b to the location of memory pointed out by pm */ { long tmul; long tadd; tmul = a*b; *pm = tmul; tadd = tmul + c; return tadd; }
amain.s (1) * assembly language version of the main function .global multadd .global printf .mri 1 section .bss product rmb 4 sum rmb 4
amain.s (2) section .text main: ; pushing arguments arg4 thru arg2 to the stack ; arg4: pm = &product ldx #product pshx ; arg3: c = 32L = 0x00000020 ldx #$0020 ldx #$0000 ; arg2: b = 17 = 0x11 ldaa #$11 psha ; storing argument arg1 in the register D ; arg1: a = 258 = 0x102 ldd #$102 jsr multadd
amultadd.s (1) ; assembly language version of the multadd function tmul_offset EQU 0 tadd_offset EQU 4 a_offset EQU 8 b_offset EQU 12 c_offset EQU 13 pm_offset EQU 17 SP IX 0 - tmul 1 - tmul 2 - tmul 10 - RTNH 3 - tmul 11 - RTNL 4 - tadd 12 - b 5 - tadd 13 - c 6 - tadd 14 - c 7 - tadd 15 - c 8 - a 16 - c 9 - a 17 - &product 18 - &product
amultadd.s (2) section .text multadd: ;--------------------------------------------------------- ; Initialization sequence, similar for different functions ; storing D register pshb psha ; reserving space for two local variables ; long tadd pshx ; long tmul ; IX set to point to the top of the stack tsx
amultadd.s (3a) ;--------------------------------------------------------- ; Part specific for the given function ; Multiplication ; tmul = a*b = (a_high * 2^8 + a_low) * b ; ACCB = b ldab b_offset,X ; ACCA = LSB of a = a_low ldaa a_offset+1,X ; ACCD = b*a_low mul ; tmul = b*a_low std tmul_offset+2,X ldd #0 std tmul_offset,X ; ACCA = MSB of a = a_high ldaa a_offset,X
amultadd.s (3b) ; ACCD = b*a_high mul ; tmul= b*a_low + (2^8)*b*a_high addd tmul_offset+1,X std tmul_offset+1,X ; *pm = tmul ldy pm_offset,X ldd tmul_offset,X std 0,Y ldd tmul_offset+2,X std 2,Y
amultadd.s (4a) ;--------------------------------------------------------- ; Addition ; tadd = c ldd c_offset,X std tadd_offset,X ldd c_offset+2,X std tadd_offset+2,X ; tadd = tadd + tmul pshX clc ldab #4 loop ldaa tadd_offset+3,X adca tmul_offset+3,X staa tadd_offset+3,X dex decb bne loop pulx ; End of part specific for the given function
amultadd.s (5) ;--------------------------------------------------------- ; Exit sequence ; restore value of the stack pointer txs ; return long result in registers IX and D ; IX:D = tadd ldx tadd_offset,X ldd tadd_offset+2,X ; deallocate space for local variables ; repeat this 8 times ins
amultadd.s (6) ins ; remove register D from the stack puly ; store return address in register IY ; repeat 7 times jmp 0,Y end
main multadd SP IX xx xx tmul xx xx xx xx tadd D xx LDD $0102 xx $01 IX xx xx tmul xx xx 4 xx xx tadd D xx LDD $0102 xx 8 $01 $01 D=a $02 $02 RTNH RTNH RTNH PSHX RTNL RTNL RTNL 12 $11 $11 $11 $11 b $00 $00 $00 $00 13 $00 $00 $00 TSX $00 PSHD c LDX PSHX $00 $00 $00 $00 JSR $20 $20 $20 $20 17 &product &product &product &product pm SP