14.1.3 示例:简单的函数和调用栈

我们来看一个简单的函数,功能为计算两个值的最大值。在没有进行优化的情况下编译它,查看输出的汇编:

列表 14-4 展示了这个例子:

Listing 14-4.maximum.c

int maximum( int a, int b ) {
    char buffer[4096];
    if (a < b) return b;
    return a;
}

int main(void) {
    int x = maximum( 42, 999 );
    return 0;
}

列表 14-5 展示了使用 objdump 进行反汇编的输出内容。

Listing 14-5.maximum.asm

0000000000400546 <maximum>:
  400546:    55                       push   rbp
  400547:    48 89 e5                 mov    rbp,rsp
  40054a:    48 81 ec 20 10 00 00     sub    rsp,0x1020
  400551:    89 bd ec ef ff ff        mov    DWORD PTR [rbp-0x1014],edi
  400557:    89 b5 e8 ef ff ff        mov    DWORD PTR [rbp-0x1018],esi
  40055d:    64 48 8b 04 25 28 00     mov    rax,QWORD PTR fs:0x28
  400564:    00 00
  400566:    48 89 45 f8              mov    QWORD PTR [rbp-0x8],rax
  40056a:    31 c0                    xor    eax,eax
  40056c:    8b 85 ec ef ff ff        mov    eax,DWORD PTR [rbp-0x1014]
  400572:    3b 85 e8 ef ff ff        cmp    eax,DWORD PTR [rbp-0x1018]
  400578:    7d 08                    jge    400582 <maximum+0x3c>
  40057a:    8b 85 e8 ef ff ff        mov    eax,DWORD PTR [rbp-0x1018]
  400580:    eb 06                    jmp    400588 <maximum+0x42>
  400582:    8b 85 ec ef ff ff        mov    eax,DWORD PTR [rbp-0x1014]
  400588:    48 8b 55 f8              mov    rdx,QWORD PTR [rbp-0x8]
  40058c:    64 48 33 14 25 28 00     xor    rdx,QWORD PTR fs:0x28
  400593:    00 00
  400595:    74 05                    je     40059c <maximum+0x56>
  400597:    e8 84 fe ff ff           call   400420 <__stack_chk_fail@plt>
  40059c:    c9                       leave
  40059d:    c3                       ret

000000000040059e <main>:
  40059e:    55                       push   rbp
  40059f:    48 89 e5                 mov    rbp,rsp
  4005a2:    48 83 ec 10              sub    rsp,0x10
  4005a6:    be e7 03 00 00           mov    esi,0x3e7
  4005ab:    bf 2a 00 00 00           mov    edi,0x2a
  4005b0:    e8 91 ff ff ff           call   400546 <maximum>
  4005b5:    89 45 fc                 mov    DWORD PTR [rbp-0x4],eax

我们把代码精简为一些可读的汇编代码,如 14-6 所示。

Listing 14-6.maximum_refined.asm

mov rsi, 999
mov rdi, 42
call maximum

...
maximum:
push rbp
mov rbp, rsp
sub rsp, 3984

mov [rbp-0x1004], edi
mov [rbp-0x1008], esi
mov eax, [rbp-0x1004]
...

Leave
ret

■Register assignment 参考 3.4.2 节,来获知为什么修改 esi 寄存器就相当于修改整个 rsi 寄存器。


我们将会跟踪函数调用以及调用前的准备工作 (见列表 14-6),并且展示在执行之后马上查看栈中的内容。

call maximum

push rbp

mov rbp, rsp

sub rsp, 3984

results matching ""

    No results matching ""