如何理解此AT&T i386汇编代码片段? [重复]

问题描述 投票:2回答:1

请查看以下代码段:

int& sum(int& num1, int& num2) {
    num1++;
    num2++;
}

00000000 <_Z3sumRiS_>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   e8 fc ff ff ff          call   4 <_Z3sumRiS_+0x4>    // why here is a jump
   8:   05 01 00 00 00          add    $0x1,%eax     

   // why 0x8, my understanding is there are in total 3 parameters
   // num2 -- 0xc(%ebp), num1 -- 0x8(%ebp), this -- 0x4(%ebp)
   // am I right????
   d:   8b 45 08                mov    0x8(%ebp),%eax

  10:   8b 00                   mov    (%eax),%eax
  12:   8d 50 01                lea    0x1(%eax),%edx        // what the heck is this?
  15:   8b 45 08                mov    0x8(%ebp),%eax
  18:   89 10                   mov    %edx,(%eax)
  1a:   8b 45 0c                mov    0xc(%ebp),%eax
  1d:   8b 00                   mov    (%eax),%eax
  1f:   8d 50 01                lea    0x1(%eax),%edx
  22:   8b 45 0c                mov    0xc(%ebp),%eax
  25:   89 10                   mov    %edx,(%eax)
  27:   90                      nop
  28:   5d                      pop    %ebp
  29:   c3                      ret    

我需要弄清楚每一行的含义,有点让我感到困惑。

assembly 32-bit att i386
1个回答
2
投票
   3:   e8 fc ff ff ff          call   4 <_Z3sumRiS_+0x4>

这不是呼叫的真正目的地,这是链接器将填充的内容。如果运行objdump -dr sum.o,您会发现它实际上是对__x86.get_pc_thunk.ax的调用。与以下add相同,以建立指向GOT的指针。 (此函数不需要一个,但您无需优化即可编译,默认情况下为-fpie。)

有关更多详细信息,请看Why does gcc generates strange code without flag -fno-pie?


[System V i386 ABI,第2.2.2节介绍了堆栈帧的结构。

System V i386 ABI Table 2.2

所以您的堆栈框架如下所示:

0xc  |      num2      |
0x8  |      num1      |
0x4  | return address |
0x0  | previous %ebp  |  <-- %ebp

有关其余说明,这是分步分析。

// as num1 and num2 are references, they represents address in assembly
   d:   8b 45 08                mov    0x8(%ebp),%eax        // load num1 to %eax
  10:   8b 00                   mov    (%eax),%eax           // load *num1 to %eax
  12:   8d 50 01                lea    0x1(%eax),%edx        // put *num1 + 1 into %edx
  15:   8b 45 08                mov    0x8(%ebp),%eax        // load num1 to %eax
  18:   89 10                   mov    %edx,(%eax)           // save *num1 + 1 at num1
  1a:   8b 45 0c                mov    0xc(%ebp),%eax        // same as above
  1d:   8b 00                   mov    (%eax),%eax
  1f:   8d 50 01                lea    0x1(%eax),%edx
  22:   8b 45 0c                mov    0xc(%ebp),%eax
  25:   89 10                   mov    %edx,(%eax)
© www.soinside.com 2019 - 2024. All rights reserved.