Search code examples
assembly68000easy68k

Why is value passed at 0(SP) is acessible only at 4(SP)?


Why is value passed at 0(SP) is acessible only at 4(SP)? for example I need to pass a number to printn by 0(SP) instead of 4(SP) (as it's used in the routine) or it will not work. What am I missing?

MOVE #12,D0
MOVE D0,0(SP)   here I use 0 offset

PRINTN:
        MOVE 4(SP),D1   |and here 4. Shoudln't be the same?
        MOVE #3,D0
        TRAP #15
        RTS

Solution

  • According to your code, I guess PRINTN is subroutine (function, procedure, etc.) and it's called using JSR. If so, you should mind the JSR functioning: it

    • decrements SP by 4
    • puts return address (beginning of the instruction following JSR) to memory by address in SP
    • puts subroutine address (from JSR instruction) to PC

    so, after it, all offsets beyond SP you knew shall be incremented by 4. And, yep, the value in 0(SP) is accessed as 4(SP) from the subroutine, 28(SP) shall be replaced in the same way with 32(SP), and so on. RTS does the reverse - it increments SP by 4.

    Moreover, each PUSH and POP change it; if you save 2 registers on stack, after these PUSHes, all offsets are additionally incremented by 8 until corresponding POPs are executed. This is easily tracked by compilers, but more hard - by humans; that e.g. would be an additional argument why x86 invented BP in addition to SP.