x86汇编除法使用EAX、AX、AL寄存器得到不一致运算结果问题
问题原因解释
核心是你的代码存在两处关联的逻辑问题,共同导致了这个现象:
- 累加步骤的操作数长度错误
第47行的add edi, [esi]没有指定操作数宽度,NASM默认会按照32位双字处理,也就是每次会从esi指向的内存地址读取4字节的数据加到edi寄存器。但你第46行仅修改了[esi]的最低1字节(把ASCII字符转成对应的数字值),剩下的3字节都是之前读入的换行符、未初始化的脏数据等无效值,最终导致edi寄存器只有最低8位是正确的累加和,高24位全是垃圾数据。 - sum存储的内容包含脏数据
第54行mov [sum], edi是把完整的32位edi写入4字节的sum变量,所以sum的高3字节全是垃圾数据,只有最低1字节是正确的和值:
- 当你使用
mov al, [sum]时:前面已经执行了xor eax, eax把整个eax寄存器清零,仅给最低8位al赋值的情况下,eax的高24位保持为0,整体值就是正确的总和,除法运算自然得到正确结果。 - 当你使用
mov ax, [sum]时:会读取sum开头的2字节,其中第二个字节就是脏数据,直接导致eax的低16位值错误。 - 当你使用
mov eax, [sum]时:会读取sum全部4字节的脏数据,得到完全错误的被除数,除法结果自然不对。
修复方案
如果要支持更大范围的求和,只需要修正累加步骤的操作数问题即可,把第47行的add edi, [esi]替换为以下两行:
movzx ecx, byte [esi] ; 把单字节数字零扩展为32位 add edi, ecx
修改后edi的完整32位都是正确的和值,后续你用mov eax, [sum]参与除法也会得到正确结果。
内容的提问来源于stack exchange,提问作者uch
相关产品推荐
相关产品推荐

