You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IDIV指令异常排查:4除以2得到错误结果-2147483646

问题分析与解决

你遇到的这个问题根源在于两个关键错误:错误读取64位数据而非32位数组元素,以及printf格式符与参数类型不匹配,咱们一步步拆解:

1. 数组元素读取的隐藏错误

你的array定义为.int(32位有符号整数),每个元素仅占4字节,但你用mov rax, [rdi]读取数据——在x86-64的Intel语法中,这条指令默认会读取8字节(64位)内存内容。也就是说,它会把数组第一个元素4和第二个元素31一起加载到rax中,最终rax的值是0x0000001F00000004(十进制214748364804),根本不是你以为的4。

你说“除法前rax和rcx的值经打印确认是正确的”,大概率是打印时也犯了格式符不匹配的错误,导致误判了rax的实际值。

2. printf格式符的类型不匹配

idiv执行后,rax存储的是64位除法结果,但你用%d(对应32位int类型)打印,这会截断rax的低32位。前面错误的rax值除以2后得到0x0000000F80000002,低32位是0x80000002,对应十进制的-2147483646——这正是你看到的错误结果。

修正后的代码

.intel_syntax noprefix
.data
outfmt: .asciz "%lld\n"  ; 用%lld匹配64位整数输出
array: .int 4,31,5,4
.text
.global main
main:
    enter 0,0
    xor rcx, rcx
    inc rcx
    inc rcx               ; rcx最终为2
    lea rdi, array
    mov eax, [rdi]        ; 读取32位数组元素,赋值eax会自动清零rax高32位,保证rax是正确的64位值4
    cqto                  ; 将rax符号位扩展到rdx,准备有符号除法
    idiv rcx              ; rax = 4/2 = 2,rdx = 0
    lea rdi, outfmt
    mov rsi, rax          ; 传递64位结果给printf
    call printf
    leave
    ret

关键修正点说明

  • 替换mov rax, [rdi]为mov eax, [rdi]:确保只读取32位数组元素,同时赋值eax会自动清空rax的高32位,保证rax中是正确的64位扩展值。
  • 格式符改为%lld:匹配x86-64中printf的64位整数参数(对应long long类型)。

如果你想继续用%d打印32位结果,也可以在除法后把rax的值转到32位寄存器,修改这部分代码即可:

idiv rcx
lea rdi, outfmt
mov esi, eax  ; 用eax的32位值传递给%d参数
call printf

内容的提问来源于stack exchange,提问作者monolith937

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:55:03