從組合語言理解C++傳參方式

鴨脖發表於2012-11-28

C++傳參方式分為傳引用和傳值,傳值是將引數的副本傳入函式,傳引用是將從引數的地址傳給函式。由於剛剛學過組合語言,而且我知道在呼叫函式之前會將函式的引數壓入堆疊,那麼我很自然想到了mov和lea。而是用vc的反彙編工具我驗證了這一點。

看如下程式:

#include "stdafx.h"
#include<iostream>
using namespace std;


void Swap(int& a,int& b){
int temp = a;
a = b;
b = temp;
cout<<"sucess"<<endl;
cout<<endl;
}


int main(int argc, char* argv[])
{
int a = 9;
int b = 8;
Swap(a,b);
cout<<a<<endl;
cout<<b<<endl;
int tem;
cin>>tem;
return 0;
}


在Swap(a,b);這條語句前設定斷點並作反彙編除錯,看到在函式呼叫處的彙編程式碼:

20:       Swap(a,b);
00401B66   lea         eax,[ebp-8]
00401B69   push        eax
00401B6A   lea         ecx,[ebp-4]
00401B6D   push        ecx
00401B6E   call        @ILT+585(Swap) (0040124e)
00401B73   add         esp,8


從這段彙編程式碼可以看出,程式先將第一個引數的有效地址儲存在eax暫存器中,然後將暫存器入棧,第二個引數也是,然後再呼叫函式,最後釋放堆疊中引數佔據的空間(堆疊從高地址向低地址增加)。現在再改成傳值:

#include "stdafx.h"
#include<iostream>
using namespace std;


void Swap(int a,int b){
int temp = a;
a = b;
b = temp;
cout<<"sucess"<<endl;
cout<<endl;
}

重新除錯,結果如下:

20:       Swap(a,b);
00401B66   mov         eax,dword ptr [ebp-8]
00401B69   push        eax
00401B6A   mov         ecx,dword ptr [ebp-4]
00401B6D   push        ecx
00401B6E   call        @ILT+145(Swap) (00401096)
00401B73   add         esp,8


從中可以看出,程式直接將第一個引數的值放入暫存器中,然後將暫存器入棧。第二個引數也是如此。最後再釋放引數佔據的記憶體空間。但是在vc中一個int佔四個位元組,這裡的dword是四個位元組嗎?或許吧,但是教材上是2個位元組啊


以上便是傳值和傳參的區別。











相關文章