Another approach on stacks


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