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

时间:2010-08-25 10:08:12

标签: c++ gcc assembly

我有以下c ++代码

int factorial(int n){

    if(n==0){
        return 1;
    }
    return n*factorial(n-1);

}

int main(void){
    factorial(5);
    return 0;
}

当我使用g ++ -S factorial.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

我可以遵循大部分内容,但.cfi和.LFE部分的目的是什么? 我在哪里可以了解更多关于gcc生成的组件的信息?

1 个答案:

答案 0 :(得分:52)

这些指令告诉gas发出Dwarf Call Frame Information标签,这些标签显然用于在帧指针丢失时重建堆栈回溯。在你的情况下,帧指针存在,所以我想它可以用于在异常处理期间执行展开。这种机制的开销比旧的sjlj(setjump / longjump)少。请参阅here以及链接的矮人规范。

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