有關copy constructor

在傳統C中,函數的參數和返回值都是以複製傳送的.
看這段代碼
struct Big
{
 char buf[1024];
}B,B2;

Big bigfun(Big b)
{
 return b;
}

int main()
{
 B2 = bigfun(B);
 return 0;
}

其中B2 = bigfun(B)要被由以下幾個過程組成
1.B要以傳值方式傳送到函數的參數表中中
2.如果返回值size很小,可以返回eax中
  但是在這裏,返回值size很大,要建立臨時變量
  然後將臨時變量的地址入棧,此時非常象函數參數入棧
  返回eax指向這個臨時變量
3.將這個臨時變量拷貝到B2上

B2 = bigfun(B);
展開爲
;構造臨時堆棧
004017AE  sub         esp,400h ;堆棧大小1024(400h)
;由於函數調用是傳值方式,所以將B複製到bigfun中的參數中
;相當於將B push到堆棧中
004017B4  mov         ecx,100h ;傳送大小1024(100h*4)
004017B9  mov         esi,offset B (421138h) ;源是B首地址
004017BE  mov         edi,esp ;目的爲bigfun中的參數地址
004017C0  rep movs    dword ptr [edi],dword ptr [esi] ;複製
;調用函數,此時push eax中的eax並非是函數參數壓棧,而是將一個臨時對象的指針壓棧
004017C2  lea         eax,[ebp-4C4h]
004017C8  push        eax ;將堆棧中一個臨時對象地址壓堆棧
004017C9  call        bigfun (401750h) ;調用函數
004017CE  add         esp,404h ;清除堆棧(400h+4),堆棧跳過函數參數表和函數返回地址
;臨時對象爲返回變量,eax指向這個地址
;將這個臨時對象複製另一個臨時對象上
004017D4  mov         ecx,100h ;傳送大小1024(100h*4)
004017D9  mov         esi,eax ;目的上面臨時對象的地址
004017DB  lea         edi,[ebp-8CCh] ;堆棧中第三個臨時對象
004017E1  rep movs    dword ptr [edi],dword ptr [esi] ;複製
;將第二個臨時對象複製到B2上
004017E3  mov         ecx,100h ;傳送大小1024(100h*4)
004017E8  lea         esi,[ebp-8CCh] ;堆棧中第三個臨時對象
004017EE  mov         edi,offset B2 (421538h) ;目的爲首地址
004017F3  rep movs    dword ptr [edi],dword ptr [esi] ;傳送


Big bigfun(Big b) {
展開爲
;初始化堆棧,以ebp爲基準,ebp+4指向爲return address
;ebp+8爲剛纔壓入堆棧的上層函數中的臨時對象的地址
;ebp-4爲臨時堆棧中第一個局部變量
00401750  push        ebp 
00401751  mov         ebp,esp ;ebp此時指向以前保存bp
00401753  sub         esp,0C0h ;建立臨時堆棧,大小0C0h
00401759  push        ebx 
0040175A  push        esi 
0040175B  push        edi
;初始化堆棧全部爲0xcc
0040175C  lea         edi,[ebp-0C0h]
00401762  mov         ecx,30h
00401767  mov         eax,0CCCCCCCCh
0040176C  rep stos    dword ptr [edi]
 return b;
;複製b到那個臨時對象上
0040176E  mov         ecx,100h
00401773  lea         esi,[b]
00401776  mov         edi,dword ptr [ebp+8] ;ebp+8爲參數表中的參數地址
00401779  rep movs    dword ptr [edi],dword ptr [esi]
;返回那個臨時變量的地址
0040177B  mov         eax,dword ptr [ebp+8]
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章