3

如何将内存地址从寄存器传递给其他?我的以下例程从堆栈接收字符串内存地址(是的,这是必要的),然后尝试放入D1寄存器,但它不起作用,当我尝试运行时,EASy68k模拟器崩溃(或进入无限循环?)。

代码:

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

更新:我更新了从堆栈推送和弹出参数的方式。更改为使用PEA看起来完全符合我要求的指令,但它仍然不起作用。

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
4

1 回答 1

2

要将参数正确放入堆栈,您需要执行以下操作:

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

或者

    PEA.L  T

要正确地将参数堆栈中取出,您实际上并不希望将其弹出到被调用的函数中。那是因为BSR推送了一个返回地址。相反,您需要使用索引寻址,如下所示:

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

然后最重要的是,您需要从调用者(而不是被调用者)的堆栈中“弹出”参数,方法是在BSR指令之后添加:

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

生成的程序(我在 EASy68K 中测试过)如下所示:

        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

并且不要忘记SIMHALT提前PRINTS。你不想从你的主代码掉入你的子程序。

哦,你可能已经发现:

        PEA.L  T(PC)

确实可以代替

        PEA.L  T

主要区别在于代码大小。第一个使用 PC 相对寻址来生成地址,而第二个将完整的 32 位地址存储在目标代码中。

于 2013-11-27T23:30:00.150 回答