【问题标题】:floating point instruction anomaly -- FLDZ malfunctioning?浮点指令异常——FLDZ 故障?
【发布时间】:2012-08-08 08:34:58
【问题描述】:

我正在尝试调试我之前在这里发布的问题: C++ and pin tool -- very weird DOUBLE variable issue with IF statement。 我使用 gdb 追踪了发生奇怪行为的时刻。我发现如下图所示,它显示了显示反汇编代码和浮点寄存器值的 gdb 屏幕截图。 (大图here) 左侧图像显示了突出显示的FLDZ 指令执行之前的屏幕截图,右侧图像显示了指令执行之后的屏幕截图。我查找了 x86 ISA,FLDZ 用于将+0.0 加载到ST(0) 中。但是,我得到的是-nan 而不是+0.0。 有人知道为什么会这样吗? 我使用的系统是运行 64 位 CentOS 的 Intel xeon 5645,但我尝试调试的目标程序是 32 位应用程序。另外,正如我在之前的帖子中提到的,我尝试了两个版本的 gcc,4.2.4 和 4.1.2,并发现了同样的问题。 谢谢。

--添加-- 顺便说一句,下面是源代码。

void Router::Evaluate( )
{
  if (_id == 0) aaa++;

  if ( _partial_internal_cycles != 0 )
  {
    aaa += 12345;
    cout << "this is not a zero : " << endl;
    on = true;
  }

  _partial_internal_cycles += (double) 1.0;

  if ( _partial_internal_cycles >= (double)1.0 ) {
    _InternalStep( );
    _partial_internal_cycles -= (double)1.0;
  }

  if (GetSimTime() > 8646000 && _id == 0) cout << "aaa = " << aaa << endl;
  if ( on)
  {
    cout << "break. id = " << _id << endl;
    assert(false);
  }

}

【问题讨论】:

  • 看起来像 FPU 堆栈溢出。你手头有源代码吗?
  • 看起来错误是在if ( _partial_internal_cycles != 0 ) 引发的。此时您的 FPU 堆栈已满。你需要以某种方式理解这是怎么回事。我熟悉的编译器会在完成计算后清空 FPU 堆栈。你用的是哪个编译器?
  • 我同意你关于错误出现的位置。另外,我使用了 gcc 4.2.4。
  • 我不使用 gcc,但我很确定它的策略必须是在完成 FPU 堆栈后清空它。当进行函数调用时,x86 ABI 肯定会要求 FPU 堆栈为空。因此,我认为您的挑战是弄清楚调用此方法时堆栈如何为非空。问题不在于您发布的代码,而在于您程序的其他地方。可以在任何地方!
  • 这是一个 pin 错误的几率很高。当您必须调试处理器时很糟糕。使用 Yahoo 群组寻求帮助。

标签: c++ x87


【解决方案1】:

产生了一个异常(注意I 位在stat 字段中设置)。正如the documentation 所说:

如果将成为新 ST(0) 的 ST(7) 数据寄存器不为空,则会检测到堆栈故障和无效操作异常,并在状态字中设置这两个标志。状态字中的 TOP 寄存器指针仍将递减,ST(0) 中的新值将是 INDEFINITE NAN。

顺便说一句,您的根本问题是因为这只是浮点的性质。这不准确。例如,请参阅 this gcc bug report -- 和 this one

【讨论】:

  • “顺便说一下,你的根本问题是因为这只是浮点的性质。它不准确。”这是真的,但与另一个问题无关。
  • 是的。比较的结果取决于精度。
  • x==0 在每次评估时都返回相同的值,只要 x 没有更改。浮点算术确实是不精确的,但是那个问题没有算术。
  • @DavidHeffernan:可能需要将x 的值从内存加载到寄存器中。如果寄存器和内存的格式不同,则需要进行格式转换才能完成加载。那是算术运算。编译器还可以将x 从寄存器写入内存,以便将其与内存中已经存在的浮点零进行比较。这也可能需要格式转换。如果标准要求比较返回true,那么它将返回true。如果它要求它返回false,它将返回false。否则,它甚至不需要是一致的。
  • 如果需要转换,每次将值加载到寄存器中时都会进行相同的转换。我认为这是一个附带问题。真正的问题显然是寄存器堆栈溢出。
猜你喜欢
  • 1970-01-01
  • 2013-10-14
  • 2014-09-22
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
  • 2017-11-07
  • 2021-09-19
  • 1970-01-01
相关资源
最近更新 更多