x64 NASM汇编64位除法未生成余数问题咨询
x64汇编idiv使用的误区分析
你的代码存在两个核心误区:
1. 误解64位有符号除法的被除数结构
idiv rbx是64位有符号除法指令,它的被除数并非仅存于RAX,而是由RDX:RAX共同组成的128位有符号数。你只将RDI的值移入RAX,但未处理RDX寄存器,此时RDX中残留的随机值会和RAX组合成完全不符合预期的128位被除数,最终导致计算结果错误。
比如你测试的场景中,若RDX的值恰好使得RDX:RAX整体是2的整数倍,余数就会是0,这就是你看到RDX=0的原因。
2. 未执行符号扩展操作
对于有符号除法,必须将RAX的符号位扩展到RDX,才能保证被除数是你预期的数值。x64架构提供cqo指令专门完成这个操作:它会把RAX的最高位(符号位)复制到RDX的所有位上——如果RAX是正数,RDX会被清零;如果RAX是负数,RDX会被设为全1。
修正后的代码如下:
mov rax, rdi ; 将被除数移入RAX cqo ; 符号扩展RAX到RDX,组成128位被除数RDX:RAX mov rbx, [_j] ; 加载除数到RBX idiv rbx ; 执行有符号除法,余数存入RDX,商存入RAX
额外需要确认:BSS段的变量_j是否被正确初始化。BSS段变量默认值为0,若未通过mov qword [_j], 2这类指令赋值,会触发除零错误,但你未遇到该问题,说明_j已被正确设置为2,这部分无需调整。
内容的提问来源于stack exchange,提问作者KnightChaser
相关产品推荐
相关产品推荐

