装配(68k)堆栈操作

时间:2013-10-01 09:28:21

标签: assembly stack

我无法使这段代码正常工作,并希望能在这里获得一些见解。

该程序应该从输入(> 0和< 300)读取两个数字并输出它们的和和产品。我们应该使用堆栈将值传递给子例程。

我的程序运行并读取输入并显示输出,但它不是正确的输出。我假设我的堆栈操作已关闭,但我无法弄清楚缺少什么。

到目前为止,这是我的代码。

编辑:除了乘法部分我有一个正常运行的代码。我确定堆栈中的下一个项目是输入数字,但乘数子程序不计算正确的产品值。任何人都可以看看子程序,并检查有什么问题?             ORG 1000美元     开始:;第一个程序指令

* 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

1 个答案:

答案 0 :(得分:1)

陷阱有点像你要跳过的子程序指针。如果是子程序(使用JSR或BSR跳转),68k需要“记住你来自哪里”。为此,他保存了地址的4个字节(实际上是te 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中的内容。

抱歉,我的Atari机器离我很远,所以没有测试;所以我不记得如果68k堆栈首先是SR然后是PC或PC然后堆叠...... :(

希望这会有所帮助 问候 彼得