2012-02-27 58 views
3
#include <stdio.h> 
int main(int argc, char * argv[]) 
{ 
argv[1][2] = 'A'; 
return 0; 
} 

以下是來自GCC的32位Intel體系結構的相應彙編代碼。我無法完全理解正在發生的事情。分析生成的彙編代碼以操作命令行參數

main: 
     leal 4(%esp), %ecx - Add 4 to esp and store the address in ecx 
     andl $-16, %esp - Store first 28 bits from esp's address into esp?? 
     pushl -4(%ecx) - Push the old esp on stack 
     pushl %ebp   - Preamble 
     movl %esp, %ebp 
     pushl %ecx   - push old esp + 4 on stack 
     movl 4(%ecx), %eax - move ecx + 4 to eax. this is the address of argv. argc stored at (%ecx). 
     addl $4, %eax - argv[1] 
     movl (%eax), %eax - argv[1][0] 
     addl $2, %eax - argv[1][2] 
     movb $65, (%eax) - move 'A' 
     movl $0, %eax - move return value (0) 
     popl %ecx - get old value of ecx 
     leave 
     leal -4(%ecx), %esp - restore esp 
     ret 

前導碼之前的代碼開始時發生了什麼?根據以下代碼,argv存儲在哪裏?在堆棧上?

+1

它可能會幫助你編譯時沒有優化,'-O0' – IanNorton 2012-02-27 21:54:52

+1

'和l -16,%esp'←在我看來像是將堆棧對齊到16個字節 – ninjalj 2012-02-27 21:57:49

+0

這可能有助於思考'andl $ -16 ,X'爲'X&0xFFFFFFF0'。 – user7116 2012-02-27 21:59:04

回答

5

您所看到的有趣代碼(前兩行)是堆棧對齊到16個字節(-16~15x & ~15相同,輪數爲16的倍數)。

argv將進入功能時被存儲在ESP + 8,什麼leal 4(%esp), %ecx確實是創建一個指針,指向包含argcargv僞結構,那麼它前進到從那裏訪問它們。 movl 4(%ecx), %eax從這個僞結構訪問argv

1

argv是「main()」的參數,所以在許多ABI中,它確實會被傳遞到堆棧上。