代码之家  ›  专栏  ›  技术社区  ›  shuttle87 Bhargav Boda

GCC从c++程序生成的汇编代码中的.cfi和.LFE是什么?

  •  31
  • shuttle87 Bhargav Boda  · 技术社区  · 14 年前

    我有以下c++代码

    int factorial(int n){
    
        if(n==0){
            return 1;
        }
        return n*factorial(n-1);
    
    }
    
    int main(void){
        factorial(5);
        return 0;
    }
    

    使用g++-S创建程序集文件时阶乘.cpp我得到以下信息:

        .file   "tail_call_opt.cpp"
        .text
    .globl _Z9factoriali
        .type   _Z9factoriali, @function
    _Z9factoriali:
    .LFB0:
        .cfi_startproc
        .cfi_personality 0x0,__gxx_personality_v0
        pushl   %ebp
        .cfi_def_cfa_offset 8
        movl    %esp, %ebp
        .cfi_offset 5, -8
        .cfi_def_cfa_register 5
        subl    $24, %esp
        cmpl    $0, 8(%ebp)
        jne .L2
        movl    $1, %eax
        jmp .L3
    .L2:
        movl    8(%ebp), %eax
        subl    $1, %eax
        movl    %eax, (%esp)
        call    _Z9factoriali
        imull   8(%ebp), %eax
    .L3:
        leave
        ret
        .cfi_endproc
    .LFE0:
        .size   _Z9factoriali, .-_Z9factoriali
    .globl main
        .type   main, @function
    main:
    .LFB1:
        .cfi_startproc
        .cfi_personality 0x0,__gxx_personality_v0
        pushl   %ebp
        .cfi_def_cfa_offset 8
        movl    %esp, %ebp
        .cfi_offset 5, -8
        .cfi_def_cfa_register 5
        andl    $-16, %esp
        subl    $16, %esp
        movl    $5, (%esp)
        call    _Z9factoriali
        movl    $0, %eax
        leave
        ret
        .cfi_endproc
    .LFE1:
        .size   main, .-main
        .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
        .section    .note.GNU-stack,"",@progbits
    

    在哪里可以了解更多关于gcc生成的程序集的信息?

    1 回复  |  直到 14 年前
        1
  •  57
  •   Waqar Andrew Tomazos    4 年前

    这些指令告诉gas发出Dwarf调用帧信息标记,这些标记显然是用来在缺少帧指针时重建堆栈回溯。在您的例子中,帧指针是存在的,所以我猜它可以用于在异常处理期间执行展开。这种机制比旧的sjlj具有更少的开销( setjump / longjump here ,以及链接的矮人规范。

    至于 .Lxx 标签, .L 前缀表示该标签是此文件的本地标签,因此不会与其他文件中的同名标签冲突。GCC通常将.L用于自动生成的标签。在这种情况下最有可能” FB 表示“函数开始”和 FE “表示”功能结束“。