1

问题1:当执行第8行时,我推断%esp和%ebp都等于CFA-4,它们指向存储在堆栈中的返回地址。这样对吗?

    :                 :
    |    whatever     | <--- CFA: the value of the stack pointer at the 
    :                 :      call site in the previous frame
    +-----------------+
    | line 43 address | <--- %ebp == CFA - 4?
    +-----------------+

大会:

  1         .file   "test_.c"
  2         .text
  3         .globl  fn1
  4         .type   fn1, @function
  5 fn1:
  6 .LFB0:
  7         .cfi_startproc
  8         pushl   %ebp
  9         .cfi_def_cfa_offset 8
 10         .cfi_offset 5, -8
 11         movl    %esp, %ebp
 12         .cfi_def_cfa_register 5
 13         subl    $16, %esp
 14         movl    $1, -8(%ebp)
 15         movl    $2, -4(%ebp)
 16         movl    -4(%ebp), %eax
 17         movl    -8(%ebp), %edx
 18         addl    %edx, %eax
 19         leave
 20         .cfi_restore 5
 21         .cfi_def_cfa 4, 4
 22         ret
 23         .cfi_endproc
 24 .LFE0:
 25         .size   fn1, .-fn1
 26         .section        .rodata
 27 .LC0:
 28         .string "count1 = %d\n"
 29         .text
 30         .globl  main
 31         .type   main, @function
 32 main:
 33 .LFB1:
 34         .cfi_startproc
 35         pushl   %ebp
 36         .cfi_def_cfa_offset 8
 37         .cfi_offset 5, -8
 38         movl    %esp, %ebp
 39         .cfi_def_cfa_register 5
 40         andl    $-16, %esp
 41         subl    $32, %esp
 42         call    fn1
 43         movl    %eax, 28(%esp)
 44         movl    $.LC0, %eax
 45         movl    28(%esp), %edx
 46         movl    %edx, 4(%esp)
 47         movl    %eax, (%esp)
 48         call    printf
 49         movl    $0, (%esp)
 50         call    exit
 51         .cfi_endproc
 52 .LFE1:
 53         .size   main, .-main
 54         .ident  "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
 55         .section        .note.GNU-stack,"",@progbits

C代码:

#include <stdio.h>
#include <stdlib.h>
int fn1()
{
    int a, b;

   a = 1;
   b = 2;

   return a + b;
}

int main()
{
    int count;

    count = fn1();
    printf("count1 = %d\n", count);

    exit(0);
}

问题2:我不知道为什么要在代码中插入.cfi_offset 5, -8 , .cfi_def_cfa_register 5 , .cfi_restore 5.cfi_def_cfa 4, 4也是如此。我找到了如何使用这些指令:

  • .cfi_offset 寄存器,偏移量
  • 寄存器的先前值保存在偏移量,从 CFA 偏移量。
  • .cfi_def_cfa_register 寄存器
  • .cfi_def_cfa_register 修改计算 CFA 的规则。从现在开始,将使用寄存器代替旧的。偏移量保持不变。
  • .cfi_restore 寄存器
  • .cfi_restore 表示 register 的规则现在与函数开始时的规则相同,在 .cfi_startproc 添加的所有初始指令都已执行之后。
  • .cfi_def_cfa 寄存器,偏移量
  • .cfi_def_cfa 定义了计算 CFA 的规则:从寄存器中获取地址并添加偏移量。

    所以我想知道1#、2#、3#……这些数字分别代表哪个寄存器。

4

0 回答 0