Intel 8080汇编程序求助:实现双数输入验证与除法功能
Intel 8080汇编程序:多位数输入与除法实现
问题分析
现有代码的核心缺陷:
INPUT_NUMBER仅调用RST 2读取单个字符,无法处理多位数输入- 验证逻辑完全错误:
VALID_FIRST直接检查D寄存器,但输入的字符并未转换成16位数值存入该寄存器 - 缺少多位数ASCII转十进制的逻辑,也未实现除法功能
核心操作选择说明
选择RST 2实现输入的原因:
RST是8080的重启指令,RST 2会跳转到系统预设的输入处理程序,自动从键盘读取一个字符,返回的ASCII码直接存于累加器A中- 对于新手来说,无需直接操作I/O端口、处理硬件时序等复杂细节,利用系统提供的成熟功能更高效、易理解
- 要实现多位数输入,只需循环调用
RST 2,逐个读取字符直到回车(ASCII0DH)即可
完整修改代码
ORG 800H JMP MAIN ; 显示以$结尾的字符串 DISPLAY MOV A,M ; 取当前字符串字符 CPI '$' ; 判断是否为结束符 JZ DISPLAY_END ; 是则终止显示 CALL DISPLAY_CHAR; 显示单个字符 INX H ; 指针移至下一个字符 JMP DISPLAY ; 循环显示 DISPLAY_END RET ; 调用RST1显示单个字符(A中存ASCII码) DISPLAY_CHAR RST 1 RET ; 读取多位数,转换为16位数值存入DE寄存器 ; 输入结束标志:回车(0DH) INPUT_16BIT_NUM LXI D,0000H ; 初始化DE为0,存储最终数值 INPUT_16_LOOP: RST 2 ; 调用RST2读入字符,ASCII码在A中 CPI 0DH ; 判断是否为回车 JZ INPUT_16_END ; 是则结束输入 CPI '0' ; 检查是否为数字字符 JC INPUT_16_ERR ; 小于'0'则非法 CPI '9'+1 ; 大于'9'则非法 JNC INPUT_16_ERR SUI '0' ; ASCII转数字:A = A - '0' ; 计算DE = DE *10 + A PUSH H XCHG ; HL = DE(当前数值) DAD H ; HL = HL*2 DAD H ; HL = HL*4 DAD H ; HL = HL*8 PUSH H ; 暂存HL*8 XCHG ; DE = HL(原数值) DAD H ; DE = DE*2 POP H ; HL = 原数值*8 DAD D ; HL = 原数值*8 + 原数值*2 = 原数值*10 MOV E,L ; DE = HL(数值*10) MOV D,H POP H MOV C,A ; 暂存新数字 MOV A,E ADD C ; E = E + 新数字 MOV E,A JNC INPUT_16_LOOP; 无进位则继续循环 INR D ; 有进位则高8位加1 JMP INPUT_16_LOOP INPUT_16_ERR: CALL ERROR ; 输入非法字符,触发报错 JMP MAIN INPUT_16_END: RET ; 读取多位数,转换为8位数值存入B寄存器 ; 输入结束标志:回车(0DH) INPUT_8BIT_NUM MVI B,00H ; 初始化B为0 INPUT_8_LOOP: RST 2 ; 读入字符,ASCII码在A中 CPI 0DH ; 判断是否为回车 JZ INPUT_8_END CPI '0' JC INPUT_8_ERR CPI '9'+1 JNC INPUT_8_ERR SUI '0' ; ASCII转数字 ; 计算B = B*10 + A MOV C,B MVI B,10 MUL B ; A = C*10 ADD C ; 不对,修正为:A = C*10 + 当前数字 ; 重新实现: MOV C,A ; 暂存当前数字 MOV A,B MVI B,10 MUL B ; A = 原B*10 ADD C ; A = 原B*10 + 当前数字 MOV B,A ; 存储新结果 JNC INPUT_8_LOOP INPUT_8_ERR: CALL ERROR JMP MAIN INPUT_8_END: RET ; 验证16位数值(DE)是否在0-65535之间 VALID_FIRST ; 16位无符号数天然范围是0-65535,只需检查输入是否合法 ; 若输入过程中数值溢出(如超过65535),DE会循环,这里简化为直接返回合法 RET ; 验证8位数值(B)是否在0-255且不为0 VALID_SECOND MOV A,B CPI 00H JZ ERROR ; 除数为0直接报错 RET ; 8位无符号数天然范围0-255,无需额外检查 ; 报错处理 ERROR LXI H,US_INPE CALL DISPLAY JMP MAIN ; 输入成功提示 SUCCESS LXI H,US_INPOK CALL DISPLAY RET ; 16位除以8位,商存入HL,余数存入B ; DE=被除数(16位),B=除数(8位) DIVIDE_16_8 MOV A,D DIV B ; 先除高8位,商在A,余数在B MOV H,A ; 商的高8位存入H MOV A,E DIV B ; 余数+低8位再除,商在A,余数在B MOV L,A ; 商的低8位存入L RET MAIN ; 输入第一个数x(0-65535) LXI H,US_INP1 CALL DISPLAY CALL INPUT_16BIT_NUM CALL VALID_FIRST CALL SUCCESS ; 输入第二个数y(0-255,不能为0) LXI H,US_INP2 CALL DISPLAY CALL INPUT_8BIT_NUM CALL VALID_SECOND CALL SUCCESS ; 计算x/y CALL DIVIDE_16_8 ; 显示商(可自行补充十进制转ASCII的显示逻辑) LXI H,US_QUOTIENT CALL DISPLAY HLT ; 字符串常量 US_INP1 DB 'Input number x (0-65535): $' US_INP2 DB 'Input number y (0-255, not 0): $' US_INPE DB 'Wrong input.$' US_INPOK DB 'Input correct.$' US_QUOTIENT DB 'Result x/y: $'
关键部分解释
多位数输入逻辑
INPUT_16BIT_NUM和INPUT_8BIT_NUM循环调用RST 2读取字符,直到用户按下回车- 每次读取数字后,通过乘10加当前数字的方式累加得到最终数值(16位存DE,8位存B)
- 加入非法字符过滤,非数字字符直接触发报错
验证逻辑调整
- 16位数值
x的范围是16位无符号数的天然范围,无需额外范围检查 - 8位数值
y增加了除数不能为0的检查,避免除法运算出错
- 16位数值
除法实现
- 利用8080的
DIV指令(8位除法),分两次计算16位除以8位:先除被除数的高8位,再用余数结合低8位继续除,最终得到16位的商
- 利用8080的
内容的提问来源于stack exchange,提问作者BringDaf
相关产品推荐
相关产品推荐

