程序集 x86-64 idivq - 浮点异常

Assembly x86-64 idivq - floating point exception

尝试在汇编 x86-64 中除以两个整数,得到 Floating point exception (core dumped) 并追溯到我的 idviq 指令。

xor %rdx, %rdx
movq %r11, %rdx // rdx now contains an integer
movq %r12, %rcx // rcx now contains an integer
idivq %rcx // floating point exception

我也尝试过不使用 rcx 寄存器,而是直接通过 r12 提供 S:

movq %r11, %rdx // rdx now contains an integer
idivq %r12 // floating point exception

用 dbg 检查寄存器显示我想要在 rdx(和 rcx)中的整数在那里。这里有什么问题?我一直在 SO 上四处寻找,到目前为止没有发现任何有用的东西。

idivq %rcx 将高半部分在 %rdx 低半部分在 %rax 的 128 位分子除以 [=13] 中的 64 位分母=].参见 the description of IDIV

您的 %rdx 似乎包含您的 64 位分子,而您根本没有初始化 %rax。因此,您将一些 128 位垃圾数除以 %rcx 中的任何内容。如果结果不适合 64 位,则会出现除法溢出异常,Unix 操作系统通常通过提供 SIGFPE(“浮点异常”)来处理该异常,尽管不涉及浮点。 (在 Unix 中没有针对整数除法溢出的特定信号,因此他们采用了这个作为最接近的信号。)

如果你的分子只有64位,把它载入%rax然后执行cqto(在Intel的命名中叫做CQO)把它sign-extend变成%rdx.然后idivq %rcx将它除以%rcx中的64位分母。请注意,在这种情况下,只有将带符号的负数最大的 64 位整数 (0x8000000000000000) 除以 -1 或除以零时才有可能发生溢出。