Motorola 68000汇编printg函数在Easy68k模拟器无输出问题求助
问题分析与修复方案
你的68000汇编程序无输出的核心原因是栈地址计算错误、循环逻辑失效、格式匹配错误,以下是具体问题和修复后的完整代码:
关键错误点
- 格式字符串地址读取错误:
printg中错误使用8(SP)获取格式串地址,实际应为16(SP)(栈中保存了3个寄存器+返回地址,共16字节偏移)。 - 循环提前终止:
DBF指令先减1再判断,导致初始值为6时直接跳转到循环结束,循环体一次都不执行。 - 八进制格式匹配错误:代码中用数字
'0'匹配格式串中的字母'O',导致八进制参数无法触发输出。 - 栈对齐与参数顺序错误:用
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
相关产品推荐
相关产品推荐

