You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Motorola 68000汇编printg函数在Easy68k模拟器无输出问题求助

问题分析与修复方案

你的68000汇编程序无输出的核心原因是栈地址计算错误、循环逻辑失效、格式匹配错误,以下是具体问题和修复后的完整代码:

关键错误点

  1. 格式字符串地址读取错误:printg中错误使用8(SP)获取格式串地址,实际应为16(SP)(栈中保存了3个寄存器+返回地址,共16字节偏移)。
  2. 循环提前终止:DBF指令先减1再判断,导致初始值为6时直接跳转到循环结束,循环体一次都不执行。
  3. 八进制格式匹配错误:代码中用数字'0'匹配格式串中的字母'O',导致八进制参数无法触发输出。
  4. 栈对齐与参数顺序错误:用MOVE.B压入进制数破坏栈对齐,且DISPLAY子程序弹出参数顺序颠倒,导致TRAP #15参数无效。

修复后的完整代码

ORG     $8000

START:
        ; 按右到左顺序压入参数
        MOVE.L  #300, -(SP)    ; 第6个参数
        MOVE.L  #11, -(SP)     ; 第5个参数
        MOVE.L  #134212, -(SP) ; 第4个参数
        MOVE.L  #92, -(SP)     ; 第3个参数
        MOVE.L  #51, -(SP)     ; 第2个参数
        MOVE.L  #23, -(SP)     ; 第1个参数

        ; 压入格式字符串地址
        LEA     FMT, A0
        MOVE.L  A0, -(SP)

        ; 调用printg子程序
        BSR     printg

        ; 清理栈:6个参数(6*4) + 格式串地址(4) = 28字节
        ADDA.L  #28, SP

        ; 终止模拟
        SIMHALT

printg:
        ; 保存会被修改的寄存器
        MOVE.L  A0, -(SP)
        MOVE.L  D0, -(SP)
        MOVE.L  D1, -(SP)
        MOVE.L  D2, -(SP)

        ; 获取格式字符串地址:栈偏移16字节(3个寄存器+返回地址)
        MOVEA.L 16(SP), A0
        BSR     LENGTH
        MOVE.B  D0, D1        ; D1 = 格式字符总数

        ; 保存格式串起始地址
        MOVE.L  A0, D2

PRINT_LOOP:
        ; 判断是否处理完所有格式字符
        TST.B   D1
        BEQ     END_PRINT

        ; 读取当前格式字符并推进指针
        MOVE.B  (A0)+, D0
        SUBQ.B  #1, D1        ; 剩余字符数减1

        ; 判断格式类型
        CMP.B   #'B', D0
        BEQ     DISPLAY_BINARY
        CMP.B   #'O', D0      ; 修复:匹配字母O而非数字0
        BEQ     DISPLAY_OCTAL
        CMP.B   #'D', D0
        BEQ     DISPLAY_DECIMAL
        CMP.B   #'H', D0
        BEQ     DISPLAY_HEXADECIMAL
        BRA     PRINT_LOOP    ; 跳过无效格式字符

DISPLAY_BINARY:
        MOVE.L  #2, -(SP)     ; 修复:用MOVE.L保证栈32位对齐
        BRA     CALL_DISPLAY
DISPLAY_OCTAL:
        MOVE.L  #8, -(SP)
        BRA     CALL_DISPLAY
DISPLAY_DECIMAL:
        MOVE.L  #10, -(SP)
        BRA     CALL_DISPLAY
DISPLAY_HEXADECIMAL:
        MOVE.L  #16, -(SP)

CALL_DISPLAY:
        ; 计算当前参数的栈偏移:总格式数-剩余数-1,转为字节偏移
        MOVE.B  #6, D0
        SUB.B   D1, D0
        SUBQ.B  #1, D0
        LSL.L   #2, D0

        ; 获取参数地址并压入栈
        MOVEA.L 16(SP), A1
        ADDA.L  #4, A1
        ADDA.L  D0, A1
        MOVE.L  (A1), -(SP)

        BSR     DISPLAY
        ADDA.L  #8, SP        ; 清理栈:数值(4)+进制(4)
        BRA     PRINT_LOOP

END_PRINT:
        ; 恢复寄存器
        MOVE.L  (SP)+, D2
        MOVE.L  (SP)+, D1
        MOVE.L  (SP)+, D0
        MOVE.L  (SP)+, A0
        RTS

LENGTH:
        MOVE.L  A0, -(SP)
        CLR.B   D0

LENGTH_LOOP:
        MOVE.B  (A0)+, D1
        BEQ     LENGTH_DONE
        ADDQ.B  #1, D0
        BRA     LENGTH_LOOP

LENGTH_DONE:
        MOVE.L  (SP)+, A0
        RTS

DISPLAY:
        ; 保存TRAP #15会使用的寄存器
        MOVE.L  D0, -(SP)
        MOVE.L  D1, -(SP)

        ; 弹出参数:栈顶是数值,次顶是进制
        MOVE.L  (SP)+, D1     ; 数值存入D1
        MOVE.L  (SP)+, D2     ; 进制存入D2

        ; 设置TRAP #15参数:D0=3(显示整数)
        MOVE.W  #3, D0
        TRAP    #15

        ; 恢复寄存器
        MOVE.L  (SP)+, D1
        MOVE.L  (SP)+, D0
        RTS

        ORG     $9000
FMT     DC.B    'B','D','O','O','H','B',0  ; 格式串:二进制、十进制、八进制、八进制、十六进制、二进制

        END     START

修复后输出效果

在Easy68k中运行会依次输出:

10111
23
27
13
140004
100101100

内容的提问来源于stack exchange,提问作者user22859428

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 22:54:53