x86汇编下使用fixed point定点数执行div指令除法结果不准确问题咨询
问题原因
你写的定点数除法代码存在两个核心错误,直接导致结果异常:
- 执行
shl dx, 8前未对dx寄存器做清零处理。16位div bx指令使用dx:ax拼接的32位值作为被除数,dx残留的随机值会让被除数完全偏离预期。 - 定点数移位逻辑错误。从代码里的8位移位判断你用的是8位小数位的Q8定点格式,Q8格式除法要求被除数先左移8位转为Q16格式再做除法,才能得到Q8格式的正确商,你单独移位
dx的操作完全不符合这个逻辑。
修复后的正确代码
; 入参:ax存Q8格式被除数1000,bx存Q8格式除数900 ; 出参:ax存Q8格式的商 mov ax, 1000 mov bx, 900 xor dx, dx ; 先清零dx,确保dx:ax初始为32位的1000 shl ax, 8 ; 被除数整体左移8位的第一步:ax低8位补0,原ax高8位存入进位标志CF rcl dx, 8 ; 第二步:把CF里的高8位移入dx低8位,此时dx:ax = 1000 << 8 = 256000 div bx ; 32位被除数除以16位除数,商存入ax,余数存入dx
结果验证
1000/900的理论值约为1.111,Q8格式下对应的整数值为 1.111 * 2^8 ≈ 284.4,整数除法取整后得到的商为284,换算为小数是284/256≈1.109,误差来自整数除法的截断,属于正常范围,如果需要更高精度可以结合余数做四舍五入处理。
注意事项
- 如果你的定点数是其他小数位的格式(比如Q16),只需要对应调整移位的位数即可。
- 运算前要判断被除数左移后的范围,避免超出32位导致
div指令触发溢出异常。
内容的提问来源于stack exchange,提问作者some_programmer
相关产品推荐
相关产品推荐

