Nie wydaje się być dyrektywa .CFI po każdym wierszu, a także nie są szerokie odmian winorośli z tych ex., .cfi_startproc
, .cfi_endproc
Etc .. więcej tutaj .
.file "temp.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl $0, %eax
leave
ret
.cfi_endproc
.LFE0:
.size main, .-main
.globl func
.type func, @function
func:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl %edi, -4(%rbp)
movl %esi, %eax
movb %al, -8(%rbp)
leave
ret
.cfi_endproc
.LFE1:
.size func, .-func
.ident "GCC: (Ubuntu 4.4.1-4ubuntu9) 4.4.1"
.section .note.GNU-stack,"",@progbits
Nie zrozumiałem ich celu.
cfi
instrukcjiGNU AS
tutajOdpowiedzi:
Mam wrażenie, że to skrót od Call Frame Information i jest rozszerzeniem GNU AS do zarządzania ramkami wywołań. Od DeveloperWorks :
Wygląda na to, że są one generowane na niektórych platformach w zależności od potrzeby obsługi wyjątków.
Jeśli chcesz je wyłączyć, zapoznaj się z odpowiedzią Davida .
źródło
:
). Zobacz stackoverflow.com/a/15285058/4294399Aby je wyłączyć, użyj opcji gcc
-fno-dwarf2-cfi-asm
może być również potrzebny.źródło
-fno-dwarf2-cfi-asm
może być również potrzebnyDyrektywy CFI służą do debugowania. Pozwala debugerowi rozwinąć stos. Na przykład: jeśli procedura A wywołuje procedurę B, która następnie wywołuje wspólną procedurę C. Procedura C kończy się niepowodzeniem. Teraz chcesz wiedzieć, kto faktycznie dzwonił do C, a następnie możesz chcieć wiedzieć, kto dzwonił do B.
Debugger może rozwinąć ten stos za pomocą wskaźnika stosu (% rsp) i zarejestrować% rbp, jednak musi wiedzieć, jak je znaleźć. I tu właśnie pojawiają się dyrektywy CFI.
więc ostatnia linia tutaj mówi, że "Adres ramki wywołania" jest teraz w rejestrze 6 (% rbp)
źródło
-fomit-frame-pointer
, jako alternatywa dla RBP (który jest domyślnie włączony z gcc lub clang-O1
i wyższymi). Jest używany przez obsługę wyjątków C ++, a także debuggery / profilery. W kodzie z tradycyjnymi wskaźnikami ramek RBP bieżąca wartość RBP zawsze wskazuje na zapisaną wartość RBP, która wskazuje na poprzednią, tworząc połączoną listę. W takim przypadku nie ma potrzeby korzystania z CFI. (Chociaż w funkcjach, które używają wskaźnika ramki, CFI cfa_register unika potrzeby większej ilości metadanych dla każdej zmiany RSP, jak to pokazujesz.)Aby je wyłączyć, g ++ potrzebuje
-fno-exceptions
razem z wymienionymi wcześniej-fno-asynchronous-unwind-tables
, pod warunkiem, że nie używasz wyjątków.źródło