2010-08-25 13 views
30

kullanıyorum bir montaj dosyası oluşturmak zamanGCC tarafından C++ programından üretilen montaj kodunda .cfi ve .LFE nedir?

int factorial(int n){ 

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

} 

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

gr ++ factorial.cpp aşağıdaki alıyorum Aşağıdaki C++ kodu -S adres:

.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 

Ben bunun en takip edebilir, ama ne .cfi ve .LFE parçalarının amacı? Gcc tarafından üretilen montaj hakkında daha fazla bilgiyi nerede bulabilirim?

+0

[Gnu Assembler (GAS) 'da kullanılan CFI yönergeleri ne için kullanılır?' In olası kopyası? (Http://stackoverflow.com/questions/2529185/what-are-cfi-directives-in-gnu-assembler-gas- kullanılmış-için) – Andrey

+3

Bu bir dupe değil. Diğer soru LFE'yi kapsamaz. – Puppy

cevap

48

Bu yönergeler, gazın bir çerçeve işaretçisi eksik olduğunda yığın backtraceini yeniden oluşturmak için kullanılan Cüce Çağrı Çerçevesi Bilgisi etiketlerini yaymasını söyler. Durumunuzda çerçeve işaretçisi mevcut, bu yüzden istisna işleme sırasında gevşemeyi gerçekleştirmek için kullanılabilir. Bu mekanizmanın eski sjlj (setjump/longjump) birinden daha az yükü vardır. Ayrıca here ve ayrıca bağlı Cüce özellikleri.

.Lxx etiketleri için, .L ön eki, etiketin bu dosya için yerel olduğunu ve bu nedenle diğer dosyalardaki aynı ad etiketleriyle çakışmayacağını belirtir. GCC genellikle otomatik olarak oluşturulan etiketler için .L kullanır. Bu durumda, büyük ihtimalle "FB", "işlev başlar" ve "FE", "işlev sonu" anlamına gelir.

+3

gerçekten çok güzel bir açıklama. – AbiusX