2012-06-17 23 views
0

因此,我已經搜索了interwebs數週,無法找到我的問題的答案。

我可以看到由gcc添加的開始符號設置了最初的兩個參數(int argc,char * argv []),我相信第三個環境參數,但是我對此有幾個問題。如果main()函數被定義爲沒有參數,它爲什麼會添加所有這些?如果它只是在沒有任何參數的情況下調用_main,它會節省空間(和技術上的處理時間)嗎? 第二個推$ 0x0的是做什麼的?我已經完成了測試,如果您嘗試遍歷命令行參數(如默認開始符號),那麼您需要在開始處推送$ 0x0,否則,如果我執行以下操作,則會創建未對齊的堆棧錯誤:

push $0x00 
call _main 
mov %eax, %edi 
call _exit 

也是我調查我發現,開始符號鏈接器當你鏈接到crt1.10.6.o

任何解釋或文件,將不勝感激

回答

1

的代碼添加_start,正如您所發現的,來自名爲的目標文件3210或類似的。該目標文件通常來自C庫的一部分源代碼。它是在無知你如何聲明你的main函數的情況下編譯的,所以它不得不假設你希望利用所有三個潛在的參數。即使main不會使用它們(如上所述,除了微不足道的空間和時間外),也沒有什麼壞處。我推測這是x86-64 ELF ABI,這意味着沒有幀指針,所以push $0x00實際上只是保持堆棧與16字節邊界對齊,正如你猜測的那樣。 (在x86-32 ELF ABI中,它也將用作幀指針鏈接列表的終止符。)

+0

謝謝!你的推論(不知道這是否是正確的語法)是正確的。 – DanZimm

+0

nw我的下一個問題是爲什麼堆棧需要對齊到16字節的邊界? – DanZimm

+0

這允許編譯器將*堆棧幀內的變量*對齊到16字節的邊界,這可以使工作更快。 – zwol