3

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

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

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

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

编辑:我有一个功能代码,除了乘法部分。我确定堆栈中的下一项是输入数字,但 Multiplier 子例程不计算正确的乘积值。任何人都可以看一下子程序并检查有什么问题吗?组织 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
4

1 回答 1

1

陷阱有点像您将在其上跳转的子程序指针。如果是子例程(使用 JSR 或 BSR 跳转),68k 需要“记住你来自哪里”。为此,他保存了被称为子程序的地址(实际上是 te PC)的 4 个字节。不同之处在于陷阱函数在监督者模式下运行。所以在陷阱函数中,你可以在你想要的地方写,在监督者模式下做你想做的事。由于监督模式保存在状态寄存器中,这意味着在进入陷阱功能之前,68k必须保存两个PC返回AND状态寄存器。PC 是 4 字节,SR 是 2,所以 68k 在 SP 上使用 6 字节来保护数据。所以首先,你必须这样做: move.w d0,-(sp) move.l d1,-(sp) trap #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 然后堆栈... :(

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

于 2014-09-18T12:43:42.613 回答