1. 程式人生 > >c語言的函式引數傳遞機制

c語言的函式引數傳遞機制


看《深入理解計算機系統》覺得深入理解了函式之間的引數傳遞,但是今天一寫程式碼就出錯了。

函式對接收進來的引數都會在自己的執行時間和空間內(棧段和暫存器)有一個拷貝所有都是,指標也是,只不過指標指向地址還是那個

程式碼一,引數為普通變數

void foo(int a)
{
        a= 1;
}


int main()
{
        int x = 6;
        foo(x);
}

對應的彙編程式碼的一部分如下:
080483ed <foo>:
 80483ed:	55                   	push   %ebp
 80483ee:	89 e5                	mov    %esp,%ebp
 80483f0:	83 ec 10             	sub    $0x10,%esp
 80483f3:	c7 45 fc 01 00 00 00 	movl   $0x1,-0x4(%ebp)
 80483fa:	c9                   	leave  
 80483fb:	c3                   	ret    

080483fc <main>:
 80483fc:	55                   	push   %ebp
 80483fd:	89 e5                	mov    %esp,%ebp
 80483ff:	83 ec 14             	sub    $0x14,%esp
 8048402:	c7 45 fc 06 00 00 00 	movl   $0x6,-0x4(%ebp)
 8048409:	8b 45 fc             	mov    -0x4(%ebp),%eax
 804840c:	89 04 24             	mov    %eax,(%esp)
 804840f:	e8 d9 ff ff ff       	call   80483ed <foo>
 8048414:	c9                   	leave  
 8048415:	c3                   	ret    
 8048416:	66 90                	xchg   %ax,%ax
 8048418:	66 90                	xchg   %ax,%ax
 804841a:	66 90                	xchg   %ax,%ax
 804841c:	66 90                	xchg   %ax,%ax
 804841e:	66 90                	xchg   %ax,%ax

可以看到foo函式只是將數1放在了自己的棧段,並不會影響main函式棧段內的資料。

程式碼2,  引數為指標

void foo(int *a)
{
        *a= 1;
}


int main()
{
        int *x, y = 6;
        x = &y;
        foo(x);
}
對應彙編:
080483ed <foo>:
 80483ed:	55                   	push   %ebp
 80483ee:	89 e5                	mov    %esp,%ebp
 80483f0:	8b 45 08             	mov    0x8(%ebp),%eax
 80483f3:	c7 00 01 00 00 00    	movl   $0x1,(%eax)
 80483f9:	5d                   	pop    %ebp
 80483fa:	c3                   	ret    

080483fb <main>:
 80483fb:	55                   	push   %ebp
 80483fc:	89 e5                	mov    %esp,%ebp
 80483fe:	83 ec 14             	sub    $0x14,%esp
 8048401:	c7 45 f8 06 00 00 00 	movl   $0x6,-0x8(%ebp)
 8048408:	8d 45 f8             	lea    -0x8(%ebp),%eax
 804840b:	89 45 fc             	mov    %eax,-0x4(%ebp)
 804840e:	8b 45 fc             	mov    -0x4(%ebp),%eax
 8048411:	89 04 24             	mov    %eax,(%esp)
 8048414:	e8 d4 ff ff ff       	call   80483ed <foo>
 8048419:	c9                   	leave  
 804841a:	c3                   	ret    
 804841b:	66 90                	xchg   %ax,%ax
 804841d:	66 90                	xchg   %ax,%ax
 804841f:	90                   	nop

可以看到在main函式裡面是將y=8的地址放在%eax裡面,又將%eax的值放在mian函式自己的棧段裡面,在foo函式裡面將傳遞進來的指標引數放在了暫存器%eax裡面,然後讓%eax指向的地址值變為1。