【问题标题】:Assembler debug of undefined expression未定义表达式的汇编程序调试
【发布时间】:2015-05-30 12:05:40
【问题描述】:

我试图更好地了解编译器如何为 undefined 表达式生成代码,例如对于以下代码:

int main()
{
    int i = 5;
    i = i++;
    return 0;
}

这是 gcc 4.8.2 生成的汇编代码(优化关闭 -O0,我插入了自己的行号以供参考):

(gdb) disassemble main
Dump of assembler code for function main:
(1) 0x0000000000000000 <+0>:    push   %rbp
(2) 0x0000000000000001 <+1>:    mov    %rsp,%rbp
(3) 0x0000000000000004 <+4>:    movl   $0x5,-0x4(%rbp)
(4) 0x000000000000000b <+11>:   mov    -0x4(%rbp),%eax
(5) 0x000000000000000e <+14>:   lea    0x1(%rax),%edx
(6) 0x0000000000000011 <+17>:   mov    %edx,-0x4(%rbp)
(7) 0x0000000000000014 <+20>:   mov    %eax,-0x4(%rbp)
(8) 0x0000000000000017 <+23>:   mov    $0x0,%eax
(9) 0x000000000000001c <+28>:   pop    %rbp
(10) 0x000000000000001d <+29>:  retq   
End of assembler dump.

执行此代码会导致 i 的值保持在 5 的值(使用 printf() 语句验证),即 i 似乎永远不会增加。我知道不同的编译器会以不同的方式评估/编译未定义的表达式,这可能只是 gcc 的方式,即我可以使用不同的编译器得到不同的结果。

关于汇编代码,据我了解:

忽略行 - 1-2 设置堆栈/基指针等。 第 3/4 行 - 5 的值如何分配给 i

谁能解释第 5-6 行发生了什么?看起来i 最终将被重新分配 5 的值(第 7 行),但增量操作(后增量操作i++ 所需)只是被编译器放弃/跳过在这种情况下?

【问题讨论】:

    标签: c assembly undefined x86-64


    【解决方案1】:

    这三行包含你的答案:

    lea    0x1(%rax),%edx
    mov    %edx,-0x4(%rbp)
    mov    %eax,-0x4(%rbp)
    

    不会跳过增量操作。 lea 是增量,取自%rax 的值并将增量值存储在%edx 中。 %edx 被存储,但随后被使用来自%eax 的原始值的下一行覆盖。

    理解此代码的关键是了解lea 的工作原理。它代表load effective address,因此虽然它看起来像一个指针解引用,但它实际上只是进行了获取 [whatever] 的最终地址所需的数学运算,然后保留该地址,而不是值 at 那个地址。这意味着它可以用于任何可以使用寻址模式有效表达的数学表达式,作为数学操作码的替代方案。由于这个原因,它经常被用作获得乘法和加法到单个指令中的一种方式。特别是,在这种情况下,它用于在一条指令中增加值并将结果移动到不同的寄存器,inc 会在原地覆盖它。

    【讨论】:

      【解决方案2】:

      第 5-6 行是i++lea 0x1(%rax),%edxi + 1mov %edx,-0x4(%rbp) 将其写回 i。但是第 7 行,mov %eax,-0x4(%rbp) 将原始值写回i。代码如下:

      (4) eax = i
      (5) edx = i + 1
      (6) i = edx
      (7) i = eax
      

      【讨论】:

        猜你喜欢
        • 2015-08-19
        • 2011-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-26
        相关资源
        最近更新 更多