我看慣了的(約定(A))引用的命令行參數:GCC:在彙編代碼中引用不同的命令行參數
pushl %ebp
movl %esp, %ebp
movl (%ebp), %eax # argc
movl 4(%ebp), %ebx # pointer to argv[0] string
movl 8($ebp), %ecx # pointer to argv[1] string
有時候,我見過的名單開始在偏移8,這不是(主要)問題。我也注意到程序是這樣的翻譯和參考,我感到困惑,讓argv[1]
(約定(B)):
movl 0xc(%ebp), %eax # pointer to a pointer to argv[0] (argc is at offset 8)
addl $0x4, %eax # argv[1] is a pointer at offset 4 from the pointer to argv[0]
movl (%eax), %eax # load where it points to, which is the argv[1] string
(在offset 16(%ebp)
我看到一個指向環境變量)
(1)這種不同的約定有什麼理由嗎?
(2)有沒有一個編譯器選項來強制gcc使用我認爲是上面的標準約定(A)?
(3)gcc使用約定(B)有什麼原因嗎?
(4)爲什麼8的附加偏移?
系統信息:
- Ubuntu的12.04
- GCC 4.6.3
- 與FNO堆棧保護器
你從哪裏得到你的約定一個代碼? AFAICT這是不正確的,因爲(在這種情況下)偏移'4(%ebp)'是'argv'本身,而不是'argv [0]'。在'8(%ebp)'是'envp'(環境塊)。 –
另外(增加一個新的註釋,因爲編輯看起來是bork'd),8的偏移量是因爲在執行'movl%esp,%ebp'時,堆棧中的前兩個項目是'%ebp',並且返回地址 - 每個是4個字節,因此是8個字節的偏移量。 –
@德魯McGowen:約定A是你會看到在任何彙編教程/書/類,並且它工作正常,當我用gcc代碼組裝氣體。至於8,如果這是主要的,爲什麼要存儲一個ret地址? (推動ebp的4人對我來說很愚蠢,應該已經注意到了)。 – gnometorule