【问题标题】:a = -2147483648 - a; compiler optimizationa = -2147483648 - a;编译器优化
【发布时间】:2011-03-30 15:21:36
【问题描述】:

我正在尝试学习如何对软件进行逆向工程以及了解编译器优化之前代码外观的所有技巧。

我多次发现这样的事情:

    if (a < 0)
      a = -2147483648 - a;

我原本以为是abs(): 下溢所以你得到了正值。但是由于a 是负数(见if),这相当于:

    if (a < 0)
      a = -2147483648 + abs(a);

这将是一个非常小的负数,而不是a 的绝对值。我错过了什么?

【问题讨论】:

  • 你没有错过任何东西。你可以使用 abs(a) | 0x80000000 代替。不知道为什么会有用。
  • From cs.cornell.edu/~tomf/notes/cps104/twoscomp.html -- "所以,对计算机来说,取一个数的负数,也就是从0中减去一个数,相当于取反加一,也就是诀窍从何而来”。

标签: c reverse-engineering compiler-optimization


【解决方案1】:

它正在转换数字,以便第 31 位成为符号位,其余位 (0...30) 表示绝对幅度。例如如果a = -5,则运算后变为0x80000005。

【讨论】:

  • 换句话说,它是从二进制补码到符号幅度的转换。 (我想知道这在典型的编译器中哪里有用。)
  • @Gilles:它可能是实际的应用程序代码,而不是编译器的优化。我只是认为这是一种优化,因为它看起来很像。
  • 有什么建议为什么逆向工程软件会经常这样做,以至于 OP 特别注意到它?我在考虑这可能是从 int 到 IEEE 754 浮点表示的软件转换的一部分,但在我看来,在这些情况下将符号位放在最后总是会更简单。
  • 对于可以以这种方式表示的整数,具有这种格式的数字对于打印带符号整数或准备在无法执行带符号版本的机器上进行乘法或除法非常有用这些操作是本机的。
  • @Pascal:我不知道。我们需要来自@Andreas 的更多背景信息。
【解决方案2】:

它似乎正在从2's complement 转换为sign-magnitude

【讨论】:

    【解决方案3】:
    【解决方案4】:

    我真诚地希望原始来源说 0x80000000 而不是 -2147483648 !十六进制数字至少给了读者一个线索。小数很神秘。

    【讨论】:

    • 因为是反编译的代码,所以我无法知道原始来源的内容。此外,这应该是一个评论。
    • 这就是为什么我说“我希望原始来源......”我假设如果你在反编译你没有原始来源。
    猜你喜欢
    • 2015-06-16
    • 1970-01-01
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 2011-08-02
    相关资源
    最近更新 更多