【问题标题】:Assembly (68k) stack operations组装(68k)堆栈操作
【发布时间】:2023-03-09 08:44:01
【问题描述】:

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

该程序应该从输入中读取两个数字(>0 和

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

这是我目前的代码。

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

【问题讨论】:

  • 你是通过调试器运行的吗?
  • 只是一个语义注​​释:从堆栈中推送不正确的 num2。东西是从堆栈中“弹出”的,而不是从堆栈中“推”出来的。 :)
  • 我用的是easy68k,调试器在哪里?
  • 当您执行bsr Adderbsr Multiplier 时,这些子例程中的代码是否考虑到bsr 在尝试访问堆栈中的操作数时将程序计数器推入堆栈?因此,操作数将在这些例程内的堆栈上的偏移量为 +4 和 +8。
  • 我已经忘记了很多关于 68k 程序集的内容,但是当您使用 (num1,A0) 寻址参数时,您期望 num1、num2(等等)偏移的值是多少,为什么?

标签: assembly stack


【解决方案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) 陷阱 #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 然后堆栈... :(

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

【讨论】:

    猜你喜欢
    • 2012-10-12
    • 1970-01-01
    • 2011-09-16
    • 2021-11-08
    • 2018-12-10
    • 2020-09-26
    • 2010-10-12
    • 2021-03-08
    • 1970-01-01
    相关资源
    最近更新 更多