是否可以使用C ++访问CPU中的溢出标志寄存器?

时间:2013-01-16 12:52:12

标签: c++ assembly flags integer-overflow

执行数学运算后,比如乘以两个整数,是否可以使用C ++访问CPU中的溢出标志寄存器?如果没有其他快速方法来检查溢出?

6 个答案:

答案 0 :(得分:9)

不,一般来说这是不可能的。有些CPU甚至没有这样的标志(例如MIPS)。

其中一条评论中提供的link将为您提供有关如何进行溢出检查的建议。

请记住,在C和C ++中,有符号的整数溢出会导致未定义的行为,而且从法律上讲,您无法在事后执行溢出检查。您需要使用无符号算术或在算术运算之前进行检查。

答案 1 :(得分:7)

我建议在每个适当的情况下阅读。来自Optimizing software in C++ -

  

整数溢出是另一个安全问题。官方C标准   说溢出的情况下有符号整数的行为是   “不确定”。这允许编译器忽略溢出或假设   它不会发生。在Gnu编译器的情况下,假设   不幸的是,没有发生有符号整数溢出   结果是它允许编译器优化掉溢出   校验。针对此问题有许多可能的补救措施:   (1)在发生之前检查溢出,(2)使用无符号整数 -   它们保证环绕,(3)陷阱整数溢出   选项-ftrapv,但这非常低效,(4)获得编译器   使用选项警告此类优化   -Wstrict-overflow=2,或(5)使用选项明确定义溢出行为   -fwrapv-fno-strict-overflow

答案 2 :(得分:1)

不。以here

预先检查的最佳方法

如果不是,还有什么其他快速方法可以检查溢出?

如果需要在操作后进行测试,则可以使用浮点数表示法(双精度)-每个32位整数都可以精确地表示为浮点数。 如果您所针对的所有机器都支持IEEE(如果不必考虑大型机,则可能是这种情况),您可以进行操作,然后对结果使用isfinite或isinf。 快速的方式(就程序员的努力而言)是:IEEE浮点算术标准(IEEE 754)定义了五个异常,每个异常返回一个默认值并具有一个对应的状态标志(在某些情况下会发生下溢除外)发生异常时引发。 五个可能的例外是:

  • 无效操作:数学上未定义,例如负数的平方根。默认情况下,返回qNaN。
  • 除以零:对有限操作数进行的运算给出确切的无限结果,例如1/0或log(0)。默认情况下,返回±无限。
  • 溢出:结果太大,无法正确表示(即,其指数范围无限制的指数将大于emax)。默认情况下,对于四舍五入到最近的模式,返回±无限(并遵循定向四舍五入模式的四舍五入规则)。
  • 下溢:结果非常小(超出正常范围)并且不精确。默认情况下,返回次正规或零(遵循舍入规则)。
  • 不精确:精确(即未取整)结果无法精确表示。默认情况下,返回正确舍入的结果。

答案 3 :(得分:0)

这可能不是你想要做的,原因有两个:

  1. 并非每个CPU都有溢出标志
  2. 使用C ++实际上无法访问溢出标志
  3. 人们之前发布的溢出检查提示可能有用。

    如果你真的想写一个乘以两个整数并检查溢出标志的快速代码,你将不得不使用汇编。如果你想要一些x86的例子,请问

答案 4 :(得分:0)

您必须执行操作并检查内联汇编中的溢出位。您可以这样做并在溢出时跳转到标签,或者(更常见但效率较低)设置变量(如果溢出)。

答案 5 :(得分:-3)

是的,有可能。您必须使用一些asm。

inline bool isOverflow() {
_asm jo isOverflow_true
return false;
isOverflow_true:return true;
}

就是这样。

编辑: 显然,不清楚在计算之后是否需要使用它来查看计算是否溢出。由于您不知道编译器将如何进行计算,因此建议您也使用asm进行计算。