2016-09-22 51 views
1

我正在學習AT & T程序集,我知道可以使用.int/.long聲明數組/變量,或者使用.equ聲明一個符號,這將被程序集取代。GCC編譯代碼:爲什麼整數聲明需要幾個語句?

它們被聲明爲.data節(初始化)或.bss節(未初始化)。

但是,當我使用gcc編譯一個非常簡單的.c文件並帶有'-S'命令行選項來檢查反彙編代碼時,我注意到: (1).s沒有同時使用.data和.bss ,但只有.data (2)整數(.long)的聲明需要幾個語句,其中一些對我來說似乎是多餘的或無用的。

如下所示,我按照我的問題添加了一些評論。

$貓NC

int i=23; 
int j; 
int main(){ 
    return 0; 
} 

$ GCC -S NC $貓NS

 .file "n.c" 
    .globl i 
    .data 
    .align 4 
    .type i, @object #declare i, I think it's useless 
    .size i, 4 #There's '.long 23', we know it's 4 bytes, why need this line? 
i: 
    .long 23  #Only this line is needed, I think 
    .comm j,4,4 #Why j is not put inside .bss .section? 
    .text 
    .globl main 
    .type main, @function 
main: 
.LFB0:     #What does this symbol mean, I don't find it useful. 
    .cfi_startproc 
    pushq %rbp 
    .cfi_def_cfa_offset 16 
    .cfi_offset 6, -16 
    movq %rsp, %rbp 
    .cfi_def_cfa_register 6 
    movl $0, %eax 
    popq %rbp 
    .cfi_def_cfa 7, 8 
    ret 
    .cfi_endproc 
.LFE0:     #What does this symbol mean, I don't find it useful. 
    .size main, .-main 
    .ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609" 
    .section .note.GNU-stack,"",@progbits 

我所有的問題都在上面的評論,我又再次強調這裏:

 .type i, @object 
    .size i, 4 
i: 
    .long 23 

我真的覺得上面的代碼是多餘的,應該如此簡單:

i: 
    .long 23 

此外,「j」沒有符號標記,也沒有放在.bss節中。

我有什麼不對嗎?請幫助糾正。非常感謝。

+2

你最好用'-fverbose-asm'編譯,也許還有'-O' –

+0

你的問題不是理解ATT程序集,而是理解ELF格式的複雜性,這很複雜(你需要幾天的閱讀理解它)。 –

+0

如果您只想看到沒有所有可預測的行的asm,您不必擔心,請參閱[我對此問題的回答](http://stackoverflow.com/questions/38552116/how-to-remove -gcc-clang-assembly-output)(或者把你的代碼放在http://gcc.godbolt中。org /) –

回答

4

(我猜你使用的是一些Linux系統)

他們宣佈insided要麼.data段(initialzed),或.bss節(uninitialzed)。

沒有,你有很多的其他部分,尤其是.comm(以下簡稱「通用」部分,以初始化數據共同到多個目標文件,鏈接器將「合併」)的只讀數據和.rodataELF格式足夠靈活,可以允許許多分區和許多分區(其中一些未加載 - 更準確地說,內存映射到內存中)。

ELF文件中各節的描述比您認爲的複雜得多。花時間閱讀更多內容,例如由Levine提供的Linkers and loaders。另請參閱文檔和的GNU binutils以及ld(1) & as(1)。使用objdump(1)readelf(1)來探索現有的ELF可執行文件,目標文件和共享對象。還閱讀execve(2) & elf(5)

但是,當我用gcc來編譯一個非常簡單的.c文件,-S命令行選項

當檢查由gcc我強烈建議至少使-fverbose-asm所產生的彙編文件請求gcc在彙編程序文件中發出一些額外的有用註釋。我通常還推薦使用一些優化標誌 - 例如至少-O1(或者最近版本gcc上的-Og)。

我注意到: (1).S是不是同時使用。數據和.bss,但只。數據

不,生成的代碼使用.comm部分,並把價值那裏有j

(2)整數(.long)的聲明花費了幾個語句,其中一些對我來說似乎是多餘的或無用的。

這些大多不彙編語句(翻譯成機器代碼),但是彙編指令;它們非常有用(並且它們不會浪費由ld生成的內存段的空間,但ELF格式在別處有信息)。特別是.size.type都是必需的,因爲ELF文件中的符號表包含多於地址(它也有尺寸的概念和類型的非常原始的概念)。

.LFB0是一個gcc(實際上是cc1 - )生成的標籤。 GCC不關心生成無用的標籤(對於GCC後端的彙編生成器來說更簡單),因爲它們不出現在目標文件中。

有」。長23' ,我們知道這是4個字節,

你可能知道,一個長爲4個字節,但該信息(的j大小)應該進入ELF文件,需要明確的彙編程序指令....

(我沒有空間或時間來解釋ELF格式,你需要閱讀很多關於它的網頁,它比你更復雜,更完整相信)

順便說一句,Drepper的How To Write Shared Libraries是相當長的(超過40頁),並解釋了關於ELF文件的一個很好的交易,側重於共享庫。

+0

我認爲'-Og'(針對調試進行優化)對於希望看到不太可怕的asm的人來說是一個很好的建議,但這幾乎完全是C源所做的。它通常比'-O1'好一些。我忘了你最近需要一個gcc版本,但是clang仍然不支持它。 –

相關問題