On the previous page, we did use pre_increment and post_decrement.
Which means, that the stackpointer is decremented before writing a word on the stack, and incremented after reading the word back from the stack.
So the stackpointer would always point to the last word which was
written/pushed on stack, pretty much like with 6809 and 68k.
Now to describe a different approach, like used by 6800 and 6502:
post_increment and pre_decrement.
Which means, that the stackpointer is decremented after writing a word on the stack, and incremented before reading the word back from the stack.
So the stackpointer would always point to the next free location
on stack, on which the next word would have to be written.
Now for the assempler macros:
pha MACRO
sta@ SP ;*SP=ACC
dec& SP ;SP-- //WARNING: take care of the Flags.
ENDM
pla MACRO
inc& SP ;SP++
lda@ SP ;ACC=*SP
ENDM
"So what ? The code won't be any faster or smaller", you might say.
Point is, that might help to reduce code size when using subroutines.
Thanks to David Cary, who sent me some code and some text about it.
First, we define three macros:
jsr# MACRO addr
mvr1@ PC to SP ;write PC+1 to the next free location on stack
jmp# addr ;the address on stack would point to the jmp#.
ENDM
At the entry point of the subroutine, we're going to correct the value
on stack by incrementing it by 2... so that said value would be the address
of the instruction word which comes after the #jmp in the previous macro.
So we need a macro to be placed at the entry point of each subroutine:
prolog MACRO
inc@ SP ; // first to correct the return address
inc@ SP ; // by incrementing it by 2.
dec& SP ;SP-- // SP points to the next free location on stack.
ENDM ; // (again, take care of the flags.)
Now the return macro to be placed at the end of the subroutine:
rts MACRO
inc& SP ;SP++ // SP now points to the return address.
jmp@ SP ; // which will be loaded into PC. that's all.
ENDM
So a subroutine would look like that:
sub_foo prolog ; // macro for correcting the return address.
;
; do some stuff
;
rts ; // macro for leaving the subroutine.
The code won't be faster than with the jsr example on the previous page,
but it takes only two instructions for calling a subroutine
instead of six, since incrementing/decrementing of the stackpointer
and correcting the return address now happens inside the subroutine.
[HOME] [UP]/ [BACK] [1] [2] [3] [4] [5] [7] [7] [8] [NEXT]
(c) Dieter Mueller 2008