PEP9汇编程序问题:字符转4位二进制输出异常求助
问题分析与修改建议
你的程序输出错误的核心原因是直接对输入字符的ASCII码进行位操作,没有先将字符转换为对应的十六进制数值:
- 字符'E'的ASCII码是
0x45(二进制01000101),字符'5'的ASCII码是0x35(二进制00110101),二者的低4位都是0x05,所以输出结果完全相同; - 你的需求是把十六进制字符(0-9、A-F)转成4位二进制,必须先把ASCII字符转换成对应的数值,再输出其二进制位。
修改方案
在存储输入字符后,新增ASCII到十六进制数值的转换逻辑:
- 若输入是
'0'-'9',减去0x30(字符'0'的ASCII码),得到0-9的数值; - 若输入是
'A'-'F',减去0x37,得到10-15的数值(比如'A'转成10,对应二进制1010); - 原程序的4位二进制输出逻辑是正确的,只需基于转换后的数值执行即可。
修改后的完整代码
CALL start start: LDBA 0xFC15,d ; 读取用户输入 CPBA 0x0058,i ; 判断是否输入'X' BREQ end ; 输入'X'则退出程序 STBA 0x0001,d ; 暂存输入的ASCII字符 ; --- 新增:ASCII转十六进制数值 --- LDBA 0x0001,d ; 加载输入字符 CPBA 0x003A,i ; 和':'的ASCII码比较(':'是'9'的下一个字符) BLO digit ; 小于':'说明是数字,跳转到数字处理 ; 处理大写字母A-F SUBA 0x0037,i ; ASCII码减0x37,得到0xA-0xF的数值 BR convert_done digit: SUBA 0x0030,i ; ASCII码减0x30,得到0-9的数值 convert_done: STBA 0x0001,d ; 存储转换后的十六进制数值 ; --- 转换逻辑结束 --- LDBA 0x0031,i ; 初始化计数器为1 STBA 0x0000,d ; 计数器存到0x0000 next_let:LDBA 0x0001,d ; 加载转换后的数值 ANDA 0x0008,i ; 检查第3位(8的位置)是否为1 CPBA 0x0000,i ; 判断ANDA结果是否为0 BREQ zero ; 为0则跳转到输出0的逻辑 one: LDBA 0x0031,i ; 加载字符'1'的ASCII码 BR print zero: LDBA 0x0030,i ; 加载字符'0'的ASCII码 print: STBA 0xFC16,d ; 输出字符 LDBA 0x0001,d ; 加载转换后的数值 ASLA ; 左移一位,准备检查下一位 STBA 0x0001,d ; 存储移位后的数值 LDBA 0x0000,d ; 加载计数器 ADDA 0x0001,i ; 计数器加1 STBA 0x0000,d ; 存储更新后的计数器 CPBA 0x0035,i ; 判断计数器是否到5(循环4次后停止) BRNE next_let ; 没到5则继续循环 LDBA 0x000D,i ; 加载回车符的ASCII码 STBA 0xFC16,d ; 输出回车 CALL start ; 回到程序开头,等待下一次输入 end: STOP ; 程序结束 .END
修改后,输入'E'会被转换为0xE(二进制1110),输入'5'转换为0x5(二进制0101),程序将正确输出对应的4位二进制值。
内容的提问来源于stack exchange,提问作者Evan Greenfield
相关产品推荐
相关产品推荐

