Что такое .cfi и .LFE в коде сборки, созданным GCC из программы С++?
У меня есть следующий код С++
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
Эти директивы сообщают газ, чтобы испускать теги информации о кадре с карликами, которые, по-видимому, используются для восстановления стоп-кадра в стеке, когда отсутствует указатель кадра. В вашем случае присутствует указатель кадра, поэтому я предполагаю, что он может использоваться для выполнения размотки во время обработки исключений. Такой механизм имеет меньше накладных расходов, чем старый sjlj (setjump/longjump). См. здесь, а также связанную специфика Dwarf.
Что касается ярлыков .Lxx, префикс .L указывает, что метка локальна для этого файла и поэтому не будет конфликтовать с одноименными метками в других файлах. GCC обычно использует .L для автогенерированных меток. В этом случае, скорее всего, "FB" означает "начало функции", а "FE" означает "конец функции".