2013-10-01 109 views
2

我無法使此代碼正常工作,並希望在此處獲得一些見解。組裝(68k)堆棧操作

該程序應該從輸入(> 0和< 300)中讀取兩個數字並輸出它們的總和和乘積。我們應該使用堆棧將值傳遞給子例程。

我的程序運行並讀取輸入並顯示輸出,但它不是正確的輸出。我假設我的堆棧操作已關閉,但我無法弄清楚缺少的東西。

這是我的代碼到目前爲止。

編輯:我有一個功能代碼,除了乘法部分。我確信堆棧中的下一個項目是輸入數字,但Multiplier子例程不計算正確的產品值。任何人都可以看看這個子程序,並檢查什麼是錯的? ORG $ 1000 START:;程序的第一條指令

* Put program code here 

First: 
    move #14,D0  Display string 
    lea  prompt1,A1 
    trap #15  
    move #4,D0  Input num1 to D1 
    trap #15 
    move.l D1,-(SP) push num1 to stack 
    move.l D1,D4  move num1 to keep 

    move.l #300,D2  Upper limit 
    cmp  D1, D2  Compare user input to upper lim 
    bhi  Second 
    blo  Error1 

Second:  
    move #14,D0  Display string 
    lea  prompt2,A1 
    trap #15  
    move #4,D0  Input num2 
    trap #15 
    move.l D1,-(SP) push num2 
    move.l #0,-(SP) make room for sum on the stack 
    move.l D1,D5  move num2 to keep 

    move.l #300,D2  Upper limit 
    cmp  D1, D2  Compare user input to upper lim 
    bhi  MoveOn 
    blo  Error2 

MoveOn: 
    *add 
    bsr  Adder 
    move.l (SP)+,D1 pull sum, D1 = sum 
    lea  (8,SP),SP clean up stack 
    move #14,D0  Display string 
    lea  result1,A1 
    trap #15 
    move #3,D0 
    trap #15 

    bsr  newLine 

    move.l D4,-(SP) push num1 to stack 
    move.l D5,-(SP) push num2 to stack 

    *multiply 
    bsr  Multiplier 
    move.l (SP)+,D1 pull product, D1 = prod 
    lea  (8,SP),SP clean up stack 
    move #14,D0  Display string 
    lea  result2,A1 
    trap #15 
    move #3,D0 
    trap #15 

    SIMHALT    ; halt simulator 

Error1: 
    move #14,D0 
    lea  error,A1 
    trap #15 
    move (SP)+,D3 Pull incorrect num1 from stack 
    bsr  newLine 
    bra  First 

Error2: 
    move #14,D0 
    lea  error,A1 
    trap #15 
    move (SP)+,D3 Pull incorrect num2 from stack 
    bsr  newLine 
    bra  Second 



*---------------------------- 
     offset 4+4 
sum  ds.l 1 
num2 ds.l 1 
num1 ds.l 1 
     org  * 

Adder 
    link A0,#0   create stack frame 
    move.l (num1,A0),D0 
    add.l (num2,A0),D0 
    move.l D0,(sum,A0)  
    move.l (SP)+,D0   
    unlk A0 
    rts 

*---------------------------- 
    offset 4+4 
prod ds.l 1 
num4 ds.l 1 
num3 ds.l 1 
     org  * 

Multiplier 
    link A0,#0   create stack frame 
    move.l (num3,A0),D0  
    mulu (num4,A0),D0  
    move.l D0,(prod,A0)  
    move.l (SP)+,D0   
    unlk A0 
    rts 

newLine 
    movem.l d0/a1,-(SP)   push d0 & a1 
    move #14,d0    task number into D0 
    lea  crlf,a1    address of string 
    trap #15     display return, linefeed 
    movem.l (SP)+,d0/a1   restore d0 & a1 
    rts       return 

* Put variables and constants here 
prompt1 dc.b 'Sláðu inn fyrri tölu: ',0 
prompt2 dc.b 'Sláðu inn seinni tölu: ',0 
error dc.b '** Tala er ekki á réttu bili, reyndu aftur **',0 
result1 dc.b 'Summa talnanna er: ',0 
result2 dc.b 'Margfeldi talnanna er: ',0 
crlf dc.b $d,$a,0 
    END START  ; last line of source 
+0

你通過調試運行呢? – Devolus

+0

只是一個語義評論:*從堆棧中推送不正確的num2 *。從堆棧中「彈出」,而不是從堆棧中「推出」。:) – lurker

+0

我正在使用easy68k,調試器在哪裏? – user2750354

回答

1

陷阱有點像您要跳轉的子例程指針。如果是子程序(使用JSR或BSR跳轉),68k需要「記住你從哪裏來」。爲此,他保存了地址的4個字節(實際上是PC),其中稱爲子程序。 區別在於陷阱函數在superviseur模式下運行。所以在一個陷阱函數裏面,你可以寫你想要的地方,做你想要的東西,因爲你處於superviseur模式。 由於監控模式保存在狀態寄存器中,這意味着在進入陷阱功能之前,68k必須保存兩臺PC才能返回AND狀態寄存器。 PC是4個字節,SR是2,因此68k使用SP上的6個字節來保護數據。 因此,首先,你必須做到: move.w D0, - (SP) move.l D1, - (SP) 陷阱#15 addq.l#6,SP 別忘後添加到SP陷阱調用,以糾正事實,在陷阱之前,你已經改變了堆棧。 在陷阱函數內部,你必須考慮68也已經把東西放在SP中的事實。 因此,您必須添加6個字節(SR爲2個字節,PC爲4個)到SP上使用的偏移量,以便取回放在其上的值。 在本例中,您可以使用陷阱功能讀取值: move.l 6(SP) - > D1 move.w 8(SP) - > D0

而且,它取決於你救什麼在你的SP裏面有陷阱功能。

對不起,我的雅達利機器離我很遠,所以沒有測試;所以,我不記得,如果68K堆棧第一SR那麼PC或PC,然後堆棧... :(

希望這有助於西港島線問候 彼得