gpt4 book ai didi

c - idiv 指令的不同结果

转载 作者:太空狗 更新时间:2023-10-29 16:39:00 26 4
gpt4 key购买 nike

看看这段代码

int main()
{
int i = 1U << 31; // assume this yields INT_MIN
volatile int x;
x = -1;
x = i / x; //dividing INT_MIN by -1 is UB
return 0;
}

它在典型平台上调用未定义的行为,但“行为”与我预期的完全不同——它的行为就像是一个无限循环。我能想到它咬人的场景。

当然 undefined 就是 undefined,但我检查了输出程序集,它使用的是普通的 idiv -- 为什么它不陷阱?为了进行比较,除以零会导致立即中止。

使用 Windows 7 64 位和 MingW64

谁能给我解释一下?

编辑

我尝试了几个选项,结果总是一样。

程序集如下:

    .file   "a.c"
.def __main; .scl 2; .type 32; .endef
.section .text.startup,"x"
.p2align 4,,15
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
subq $56, %rsp
.seh_stackalloc 56
.seh_endprologue
call __main
movl $-1, 44(%rsp)
movl $-2147483648, %eax
movl 44(%rsp), %ecx
cltd
idivl %ecx
movl %eax, 44(%rsp)
xorl %eax, %eax
addq $56, %rsp
ret
.seh_endproc
.ident "GCC: (x86_64-posix-sjlj, built by strawberryperl.com project) 4.8.2"

最佳答案

您观察到的无限循环可以说是 MinGW-w64 中的一个错误。

MinGW-w64 部分支持 SEH,如果您在调试器中运行您的代码,您将看到异常处理程序(名为“_gnu_exception_handler”的函数)由于无效的 idiv 而被调用。 (例如在 gdb 中运行您的程序并在 _gnu_exception_handler 上设置断点)

简单地说,这个异常处理程序在整数溢出的情况下所做的只是消除异常并在异常发生的地方继续执行 (idiv)。然后再次执行 idiv 操作,导致相同的溢出触发相同的错误处理程序,您的 CPU 在 idiv 和异常处理程序之间来回切换。(这是 MinGW-w64 的行为可以被视为错误的地方。)

源码里可以直接看here如果你想深入。

_gnu_exception_handler 在处理 EXCEPTION_INT_OVERFLOW(整数溢出)时返回的值“EXCEPTION_CONTINUE_EXECUTION”助长了此行为(当系统看到处理程序返回 EXCEPTION_CONTINUE_EXECUTION 时,它会跳回到生成异常的指令并尝试再次执行。)

如果您有兴趣了解更多详情,here是了解 SEH 如何在 Windows 上工作的好资源。

关于c - idiv 指令的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25363379/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com