[英]What are .LFB .LBB .LBE .LVL .loc in the compiler generated assembly code
當我查看 GCC 生成的匯編代碼時,有很多行以.LBB
和一個數字.LBB
。 似乎它們不是操作說明。 更像是標記文件的某些內容或什么。
什么是.LFB
、 . LVL
、 LBB
、 LBE
等是否在編譯器生成的匯編代碼中? .loc 是否意味着“代碼行”。 這些行只是表示symbol table
嗎?
這是一段代碼,
main:
.LFB1:
.loc 1 8 0
.cfi_startproc
.LVL2:
.LBB4:
.LBB5:
.loc 1 2 0
movsd b(%rip), %xmm0
.LBE5:
.LBE4:
.loc 1 10 0
xorl %eax, %eax
.LBB7:
.LBB6:
.loc 1 2 0
mulsd a(%rip), %xmm0
.LBE6:
.LBE7:
.loc 1 9 0
movsd %xmm0, a(%rip)
.LVL3:
.loc 1 10 0
ret
.cfi_endproc
.loc
正如 Ferruccio 所提到的.loc
是一個調試指令,如果您告訴編譯器使用-ggdb
生成調試信息,它只會出現在 GCC 4.8.2 中。
.loc
記錄在https://sourceware.org/binutils/docs-2.18/as/LNS-directives.html#LNS-directives並且確切的輸出取決於調試數據格式(DWARF2 等)。
另一個是標簽。
.L 前綴
GCC 使用.L
作為本地標簽。
默認情況下,GAS 不會在編譯輸出上生成任何符號,如文檔所述: https : //sourceware.org/binutils/docs-2.18/as/Symbol-Names.html
局部符號是任何以特定局部標簽前綴開頭的符號。 默認情況下,ELF 系統的本地標簽前綴是“.L”
局部符號在匯編器中定義和使用,但它們通常不保存在目標文件中。 因此,它們在調試時不可見。 您可以使用`-L' 選項(參見包含本地符號:-L)來保留目標文件中的本地符號。
因此,如果您使用以下命令編譯: as -c aS
, nm ao
根本不會顯示這些標簽。
這才有意義,因為您不能從 C 程序生成這樣的標簽。
還有一些選項可以管理它,例如:
man as
:-- --keep-locals
man ld
: --discard-all
這似乎是 GCC 工具鏈特定的約定,而不是 ELF ABI 或 NASM 的一部分。
此外,NASM 和 GAS 都使用以句點開頭的標簽(GAS 中的.L
除外)生成本地符號的約定: http : //www.nasm.us/doc/nasmdoc3.html#section-3.9仍然存在在輸出上,但不跨對象文件使用。
后綴
您提到的后綴似乎都與調試相關,因為它們都在 GCC 4.8.2 上的gcc/dwarf2out.c下定義,而DWARF2是 ELF 的主要調試信息格式:
#define FUNC_BEGIN_LABEL "LFB"
#define FUNC_END_LABEL "LFE"
#define BLOCK_BEGIN_LABEL "LBB"
#define BLOCK_END_LABEL "LBE"
ASM_GENERATE_INTERNAL_LABEL (loclabel, "LVL", loclabel_num);
根據我的實驗,其中一些僅使用gcc -g
生成,其他甚至沒有g
。
一旦我們有了這些定義名稱,就很容易生成 C 代碼來生成它們以了解它們的含義:
LFB
和LFE
在函數的開頭和結尾生成
LBB
和LBE
由以下代碼在內部功能塊范圍內使用gcc -g
生成:
#include <stdio.h> int main() { int i = 0; { int i = 1; printf("%d\\n", i); } return 0; }
LVL
: TODO 我無法輕易理解它。 我們需要更多地解釋來源。
.loc
指令用於指示相應的源代碼行。 它表示相應源代碼的文件號、行號和列號。
其余的看起來像標簽。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.