Question

How do I pass a memory address from a register to other? My following routine receive the string memory address from stack (yes, it's necessary) and then try to put into D1 registers but it doesn't work and EASy68k emulator crash (or goes in an infinite loop?) when I try run this.

Code:

START ORG $1000


    MOVE.L T,D0
    MOVE.L D0,-(SP)
    BSR PRINTS



PRINTS:       
        MOVE.L D0,(SP)+
        MOVE.W D0,A1
        MOVE #14,D0
        TRAP #15
        RTS

T DC.B 'HELLO',0
    END START

UPDATE: I updated the way as arguments are pushed and poped from stack. Changed to use PEA instruction that looks like do exactly what I want to but it still doesn't work.

START ORG $1000
        PEA T(PC)
        *MOVE.L D0,-(SP)
        BSR PRINTS
        ADDQ.L #4,SP

    MOVE #9,D0       
        TRAP #15 

PRINTS:        
        MOVE 4(SP),A1
        MOVE #14,D0
        TRAP #15
        RTS
Was it helpful?

Solution

To get the argument onto the stack correctly, you either need to do:

    LEA    T,  A0
    MOVE.L A0, D0
    MOVE.L D0, -(SP)

or

    PEA.L  T

To get the argument off the stack correctly, you don't actually want to pop it in the called function. That's because BSR pushes a return address. Instead, you need to use indexed addressing as follows:

    MOVE.L (4,SP), A1  ; read argument from stack, overlooking return address

And then to top it off, you need to "pop" the argument from the stack in the caller (not the callee), by adding this after the BSR instruction:

    ADDA.L #4, SP      ; remove argument from stack.

The resulting program (which I did test in EASy68K), looks like this:

        ORG    $1000
START:  
        PEA.L  T           ; push argument to stack
        BSR    PRINTS      ; call PRINTS; also pushes return address on stack
        ADDA.L #4, SP      ; remove argument from stack.
        SIMHALT

PRINTS:
        MOVE.L (4,SP), A1  ; read argument from stack, overlooking return address
        MOVE.L #14, D0
        TRAP   #15
        RTS

T       DC.B   'HELLO', 0

        END    START        ; last line of source

And don't forget that SIMHALT ahead of PRINTS. You don't want to fall from your main code into your subroutines.

Oh, and as you've likely discovered:

        PEA.L  T(PC)

does work in place of

        PEA.L  T

The main difference is code size. The first one uses PC-relative addressing to generate the address, while the second stores the full 32-bit address in the object code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top