2013-11-27 33 views
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 

回答

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位地址存儲在目標代碼中。

+0

是的。謝謝。我解決了這個問題,但它看起來像是問題的一半。它仍然不起作用。 –

+0

不應該'MOVE.L T,D0'是'LEA T,D0'?你想要T的地址,而不是T的內容。 –

+0

此舉將以與當前代碼相同的方式工作。 'LEA T,D0'返回一個錯誤:'錯誤:無效的尋址模式' –