x86-64汇编程序中使用eax而非rax赋值sum的问题咨询
问题解答
这个问题的核心是操作数宽度匹配规则和x86-64架构的隐式操作特性共同导致的,具体原因如下:
- 你当前正确写法
mov dword [rdx], eax的逻辑是完全合规的:显式指定目标内存为32位双字,源操作数eax也是32位寄存器,宽度匹配。你定义的sum是dq类型的64位变量,初始值全为0,将低32位写入6之后,整个64位的sum值就是0x0000000000000006,用PRINT_DEC 8输出64位数值自然得到正确结果6。 - 改用
rax出错的最常见原因是没有同步修改操作数宽度修饰符:如果你只是把eax替换为rax,保留了前面的dword修饰,就会出现mov dword [rdx], rax的非法写法,dword要求32位操作数,rax是64位寄存器,二者宽度不匹配,汇编器要么直接截断rax的高32位,要么生成错误的机器码,最终写入内存的值不符合预期。 - 就算你去掉
dword修饰,直接写mov [rdx], rax,理论上也应该正常工作(rax是64位,汇编器会自动识别为写入8字节的qword操作,把完整的6写入sum的8字节空间),但这里还有一个隐藏坑:你后续使用的cdq和idiv esi都是32位指令,cdq会修改rdx的低32位(即edx寄存器),且x86-64架构下修改32位寄存器会自动将对应64位寄存器的高32位清零,如果你不小心把sum的写入操作挪到了cdq之后,rdx已经被修改为非sum地址的其他值,写入就会完全错误。
补充优化建议
如果你要适配64位变量的完整写入,建议显式指定操作数宽度:mov qword [rdx], rax,避免汇编器产生歧义。如果需要做64位除法,可替换为cqo+idiv rsi的组合,符合64位寄存器的操作规范。
内容的提问来源于stack exchange,提问作者Phoebus Shi
相关产品推荐
相关产品推荐

