【问题标题】:32 bit signed integer division gives 0x7fffffff as quotient on PowerPC32 位有符号整数除法将 0x7fffffff 作为 PowerPC 上的商
【发布时间】:2015-06-07 16:20:27
【问题描述】:

我正在调试一个用 C 编写的生产代码,其最简单的形式可以显示为 -

void
test_fun(int sr)
{   
    int hr = 0;
    #define ME 65535
    #define SE 256

    sr = sr/SE;             <--  This should yield 0
    if(sr == 1)
        hr = ME;
    else
        hr = (ME+1)/sr;     <-- We should crash here.
}

我们将 sr 作为 128 传递,理想情况下应该在处理器中产生除以零错误。我看到这个除法成功发生,商为 0x7ffffffff(hr 是这个值)。 当我使用 gcc 在 Intel 平台上编译和运行它时,不会发生这种情况(尝试除以零时会崩溃)。

想知道这个大商背后的原理。不确定这是否只是我还需要发现的其他错误。 有人可以帮助我完成另一个相同的程序吗?

【问题讨论】:

  • 整数除以零产生未定义的行为。您应该对sr == 0 执行显式检查。
  • 我相信,在 PowerPC 上它会产生某种异常。它是在某些操作系统上运行还是在裸机上运行?
  • @Eugene : 它有 NetBSD 5.1 作为操作系统
  • @EugeneSh。根据this,它只是设置了一堆标志(编译器可能会忽略)
  • @harold 这是一个运行时错误,所以编译器不在循环中。我相信在 *nix-like 系统上应该发出 SIGFPE 信号。

标签: c integer-division divide-by-zero integer-arithmetic powerpc


【解决方案1】:

除以零是undefined behaviour,参见C11 standard6.5.5#5(最终草案)。

获取陷阱或 SIGFPE 只是 CPU/OS 的礼貌。 PowerPC 作为典型的 RISC CPU 不会捕捉到它,因为它可以在进行实际除法之前通过简单检查除数来安全地检测到。 x86 OTOH确实捕捉到了这种典型的 CISC 行为。

如果更高层标准要求,您可能错过了自动发出此检查的编译器选项。例如,POSIX 不强制执行 SIGFPE,这是可选的。

【讨论】:

  • 谢谢。但是我认为这个商的大值是一些数字算法的结果。也需要一些指示。
  • @RIPUNJAYTRIPATHI:长除法。
  • @Oliver Charlesworth :我仍在寻找这种长除法算法。从您的直觉来看,算法会生成这种商,还是只是在处理器级别对除数进行验证的结果中放置一个不同/唯一的值来表示错误。换句话说,除数为0的不同分子是否有可能生成不同的商值?
  • @RIPUNJAYTRIPATHI:您必须向 IBM 询问他们是如何在芯片中实际实现分区的。除了芯片设计师之外,没有人可以帮助您。请阅读关于未定义行为的定义。这实际上意味着:任何事情都可能发生。你的电脑可能会长脚然后逃跑。
  • @Adam.at.Epsilon:实际上,在 x86 上也不能保证获得 SIGFPE。 Taht 取决于操作系统等。如果您在 x86 上运行代码裸机,则需要为除零异常设置中断处理程序。这完全由您自行决定。
【解决方案2】:

根据 PPC 架构手册(您可以从 IBM 获得),在 PPC 上除以 0 不会导致任何类型的信号或陷阱;相反,您只会得到一些因处理器而异的未定义值。在您的情况下,当您将正数除以 0 时,它看起来会生成 MAXINT(最大正整数)的特定 PPC 变体。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 2013-12-22
    相关资源
    最近更新 更多