如果一个对象很小,寄存器可以放得下,一般是通过寄存器返回的,这个寄存器一般是EAX,但是如果对象足够大,以至于寄存器放不下,那么编译器是如何处理这个对象的传递和放回的呢?
code:
#include "stdafx.h"
struct big { char buf[100]; int i; // long d; } B, B2;
big bigfun(big b) { b.i = 100; return b; }
int main(int argc, char* argv[]) { B2 = bigfun(B); return 0; }
用vc++6.0生成的汇编代码为: TITLE E:\code\th_in_c++\passtruc\passtruc.cpp .386P include listing.inc if @Version gt 510 .model FLAT else _TEXT SEGMENT PARA USE32 PUBLIC 'CODE' _TEXT ENDS _DATA SEGMENT DWORD USE32 PUBLIC 'DATA' _DATA ENDS CONST SEGMENT DWORD USE32 PUBLIC 'CONST' CONST ENDS _BSS SEGMENT PARA USE32 PUBLIC 'BSS' _BSS ENDS $$SYMBOLS SEGMENT BYTE USE32 'DEBSYM' $$SYMBOLS ENDS $$TYPES SEGMENT BYTE USE32 'DEBTYP' $$TYPES ENDS _TLS SEGMENT DWORD USE32 PUBLIC 'TLS' _TLS ENDS ; COMDAT ?bigfun@@YA?AUbig@@U1@@Z _TEXT SEGMENT PARA USE32 PUBLIC 'CODE' _TEXT ENDS ; COMDAT _main _TEXT SEGMENT PARA USE32 PUBLIC 'CODE' _TEXT ENDS FLAT GROUP _DATA, CONST, _BSS ASSUME CS: FLAT, DS: FLAT, SS: FLAT endif PUBLIC ?B@@3Ubig@@A ; B PUBLIC ?B2@@3Ubig@@A ; B2 _BSS SEGMENT ?B@@3Ubig@@A DB 068H DUP (?) ; B ?B2@@3Ubig@@A DB 068H DUP (?) ; B2 _BSS ENDS PUBLIC ?bigfun@@YA?AUbig@@U1@@Z ; bigfun ; COMDAT ?bigfun@@YA?AUbig@@U1@@Z _TEXT SEGMENT _b$ = 12 $T241 = 8 ?bigfun@@YA?AUbig@@U1@@Z PROC NEAR ; bigfun, COMDAT ; File E:\code\th_in_c++\passtruc\passtruc.cpp ; Line 12 push ebp mov ebp, esp sub esp, 64 ; 00000040H push ebx push esi push edi lea edi, DWORD PTR [ebp-64] mov ecx, 16 ; 00000010H mov eax, -858993460 ; ccccccccH rep stosd ; Line 13 mov DWORD PTR _b$[ebp+100], 100 ; 00000064H ; Line 14 mov ecx, 26 ; 0000001aH lea esi, DWORD PTR _b$[ebp] mov edi, DWORD PTR $T241[ebp] rep movsd ;复制返回值 mov eax, DWORD PTR $T241[ebp] ;EAX中存放的是返回值地址 ; Line 15 pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 ?bigfun@@YA?AUbig@@U1@@Z ENDP ; bigfun _TEXT ENDS PUBLIC _main EXTRN __chkesp:NEAR ; COMDAT _main _TEXT SEGMENT $T244 = -104 $T245 = -208 _main PROC NEAR ; COMDAT ; Line 18 push ebp mov ebp, esp sub esp, 272 ; 00000110H push ebx push esi push edi lea edi, DWORD PTR [ebp-272] mov ecx, 68 ; 00000044H mov eax, -858993460 ; ccccccccH rep stosd ; Line 19 sub esp, 104 ; 00000068H mov ecx, 26 ; 0000001aH mov esi, OFFSET FLAT:?B@@3Ubig@@A ; B mov edi, esp rep movsd ;将参数压栈 lea eax, DWORD PTR $T245[ebp] push eax ;保存断点 call ?bigfun@@YA?AUbig@@U1@@Z ; bigfun add esp, 108 ; 0000006cH mov esi, eax mov ecx, 26 ; 0000001aH lea edi, DWORD PTR $T244[ebp] rep movsd mov ecx, 26 ; 0000001aH lea esi, DWORD PTR $T244[ebp] mov edi, OFFSET FLAT:?B2@@3Ubig@@A ; B2 rep movsd ;将结果赋给B2 ; Line 20 xor eax, eax ; Line 21 pop edi pop esi pop ebx add esp, 272 ; 00000110H cmp ebp, esp call __chkesp mov esp, ebp pop ebp ret 0 _main ENDP _TEXT ENDS END
|