汇编语言算术运算咨询:(x1+x2)/(x1*x2)最优实现方案求解
汇编实现
(x1+x2)/(x1*x2)的优化方案 原代码的核心问题
- 除法逻辑错误:
step_3中subb a, res_hi是严重错误,应该用除数的高字节tmp_hi参与减法,否则每次都是减自身,永远得不到正确的借位和余数。 - 效率低下:盲目用循环减法实现除法,未提前判断被除数与除数的大小关系,会做大量无意义的循环。
- 缺少异常处理:未判断除数
x1*x2为0的情况(当x1或x2为0时,除法无意义)。 - 变量命名模糊:
zero实际存储的是商,命名不直观,增加代码理解成本。
优化思路(针对8051汇编)
- 修正除法逻辑:正确实现双字节带借位减法,对应被除数(
x1+x2扩展为双字节)与除数(x1*x2双字节)的运算。 - 提前大小判断:先比较被除数和除数的高低字节,若被除数小于除数,直接返回商0,避免无效循环。
- 增加异常判断:检测除数是否为0,避免非法运算。
- 简化变量与寄存器使用:减少冗余内存变量,用更语义化的命名提升可读性。
优化后的代码
org 0000h ; 变量地址定义 x1: equ 30h ; 输入操作数1(单字节) x2: equ 31h ; 输入操作数2(单字节) quotient: equ 40h ; 运算结果-商(单字节) remainder_hi: equ 41h ; 运算结果-余数高字节 remainder_lo: equ 42h ; 运算结果-余数低字节 divisor_hi: equ 50h ; 除数高字节(x1*x2的高8位) divisor_lo: equ 51h ; 除数低字节(x1*x2的低8位) start: ; 计算被除数:x1+x2,扩展为双字节 mov a, x1 add a, x2 mov remainder_lo, a ; 低字节存x1+x2的值 clr a mov acc.0, c ; 高字节存加法进位(0或1,因x1+x2最大为510) mov remainder_hi, a ; 计算除数:x1*x2,结果为双字节 mov a, x1 mov b, x2 mul ab ; 乘积高8位在B,低8位在A mov divisor_hi, b mov divisor_lo, a ; 检查除数是否为0(x1或x2为0时触发) mov a, divisor_hi orl a, divisor_lo jz divisor_zero ; 除数为0,跳转错误处理 ; 判断被除数是否小于除数,直接返回商0 mov a, remainder_hi clr c subb a, divisor_hi jc quotient_zero ; 被除数高字节更小,商为0 jnz start_div_loop ; 被除数高字节更大,进入除法循环 mov a, remainder_lo subb a, divisor_lo jc quotient_zero start_div_loop: mov quotient, #0 div_loop: ; 双字节带借位减法:被除数 -= 除数 clr c mov a, remainder_lo subb a, divisor_lo mov remainder_lo, a mov a, remainder_hi subb a, divisor_hi mov remainder_hi, a jc div_end ; 不够减,退出循环 inc quotient ; 够减,商加1 sjmp div_loop ; 继续循环(实际最多循环2次,因x1+x2最大510,x1*x2最小1) quotient_zero: mov quotient, #0 sjmp div_end divisor_zero: ; 除数为0的错误处理,用0xFF标记异常 mov quotient, #0FFh sjmp div_end div_end: ret
优化细节说明
- 提前判断减少循环:通过高低字节的比较,直接跳过不必要的减法循环,在被除数小于除数的场景下,运算效率提升100%。
- 逻辑修正:将原代码中错误的
subb a, res_hi改为subb a, divisor_hi,还原除法的核心逻辑。 - 异常防护:新增除数为0的检测,避免程序进入非法运算状态。
- 可读性提升:将
zero改为quotient,变量语义清晰,后续维护更便捷。
内容的提问来源于stack exchange,提问作者Alexander Gess
相关产品推荐
相关产品推荐

