6502汇编:日志语句后输出整数的实现问题
问题分析与修复方案
你的核心问题有两个:一是字符串数据被当作指令执行,程序无法进入第二组循环代码;二是第二组循环的自增逻辑错误,且数值输出未正确处理十六进制字符(导致0xA显示为NULL)。
问题1:字符串阻塞代码流
你将日志字符串直接放在第一组循环和第二组循环的代码中间,当输出字符串的例程执行完毕后,程序计数器会自动指向字符串的第一个字节(0x54,即字符'T'),并将这些ASCII码当作6502指令执行(比如0x54是LDY #$54,0x68是PLA等),导致程序跑飞,根本不会执行后面的第二组循环代码。
问题2:第二组循环的自增逻辑错误
第二组循环中,你用0x6D,0x91,0x00(ADC $0091)实现数值自增,但ADC是带进位加法,你既没有清除进位标志,也没有将计算结果存回$0090(当前要输出的数值变量),这会导致数值计算错误,循环无法正常运行。同时,模拟器的$FF输出例程未处理0xA(十进制10)对应的字符,才会显示NULL。
修复步骤
1. 调整代码结构,跳过字符串数据
将日志字符串移到代码最末尾,或者在输出字符串的代码后添加跳转指令,直接跳到第二组循环的起始地址。例如,假设第二组循环起始地址是$0070,就在输出字符串后添加:
0x4C, 0x70, 0x00 // JMP $0070 跳转到第二组循环
2. 修正第二组循环的自增逻辑
将第二组循环的自增部分修改为正确的数值累加逻辑,确保每次输出后数值加1并存回变量:
// 原错误代码片段 0xFF, // 输出当前数值 0x6D,0x91,0x00, // ADC $0091(错误) 0xAA, // TAX // 修正后代码片段 0xFF, // 输出当前数值 0xAD,0x90,0x00, // LDA $0090 加载当前数值 0x18, // CLC 清除进位标志 0x69,0x01,0x00, // ADC #1 数值加1 0x8D,0x90,0x00, // STA $0090 存回变量 0xA8, // TAX 将数值加载到X用于循环比较
3. 适配十六进制字符输出
在调用$FF输出前,添加数值转字符的逻辑,让0-9输出'0'-'9',10-15输出'A'-'F':
0xAD,0x90,0x00, // LDA $0090 加载要输出的数值 0xC9,0x0A, // CMP #10 判断是否大于等于10 0x90,0x02, // BCC +2 小于10则跳转到加'0'的逻辑 0xE9,0x0A, // SBC #10 数值减10 0x69,0x41,0x00, // ADC #0x41 加上'A'的ASCII码 0x4C,0x02,0x00, // JMP +2 跳转到输出 0x69,0x30,0x00, // ADC #0x30 加上'0'的ASCII码 0xFF, // 输出字符
修复后核心代码示例
// 第一组循环(修正数值转字符逻辑) 0xA9,0x00,0x8D,0x60,0x00, 0xA9,0x01,0x8D,0x61,0x00, 0xA9,0x06,0x8D,0x62,0x00, 0xAD,0x61,0x00, // 数值转字符 0xC9,0x0A, 0x90,0x02, 0xE9,0x0A, 0x69,0x41,0x00, 0x4C,0x02,0x00, 0x69,0x30,0x00, 0xFF, // 数值自增 0xAD,0x61,0x00, 0x18, 0x69,0x01,0x00, 0x8D,0x61,0x00, 0xA8, 0xEC,0x62,0x00, 0xD0,0xE7, // 输出字符串并跳转 0xA2,0x32, // LDX #字符串长度(你的日志字符串共50字节) 0x20,0xFF,0x00, // JSR $FF 调用字符串输出子程序 0x4C,0x70,0x00, // JMP $0070 跳转到第二组循环 // 日志字符串(移到此处) 0x54,0x68,0x69,0x73,0x20,0x49,0x73,0x20,0x5A,0x65,0x72,0x6F,0x20,0x50,0x6C,0x75,0x73,0x20,0x4F,0x6E,0x65,0x20,0x54,0x68,0x65,0x6E,0x20,0x4F,0x6E,0x65,0x20,0x50,0x6C,0x75,0x73,0x20,0x4F,0x6E,0x65,0x20,0x46,0x6F,0x75,0x72,0x20,0x54,0x69,0x6D,0x65,0x73, // 第二组循环(修正后) 0xA9,0x06,0x8D,0x90,0x00, 0xA9,0x0B,0x8D,0x92,0x00, 0xAD,0x90,0x00, // 数值转字符 0xC9,0x0A, 0x90,0x02, 0xE9,0x0A, 0x69,0x41,0x00, 0x4C,0x02,0x00, 0x69,0x30,0x00, 0xFF, // 数值自增 0xAD,0x90,0x00, 0x18, 0x69,0x01,0x00, 0x8D,0x90,0x00, 0xA8, 0xEC,0x92,0x00, 0xD0,0xE7, 0x00
内容的提问来源于stack exchange,提问作者Liam Knipper
相关产品推荐
相关产品推荐

