当前位置 : 主页 > 网络编程 > 其它编程 >

C++中函数中参数和返回值都是用户定义类型(这里主要是类的情况时的分析)

来源:互联网 收集:自由互联 发布时间:2023-07-02
以下这个程序中使用了参数传值和返回值传值的操作classA{public:A(){i0;}A(constA}private:inti;} 以下这个程序中使用了参数传值和返回值传值的操作class A{public:    A()    {        i 0;   
以下这个程序中使用了参数传值和返回值传值的操作classA{public:A(){i0;}A(constA}private:inti;} 以下这个程序中使用了参数传值和返回值传值的操作class A{public:    A()    {        i 0;    }    A(const A c.i;    }private:    int i;};A funbyValue(A c){    return c;}void main(int argc,char* argv[]){   A b;   funbyValue(b);}该程序相应的汇编代码如下环境使用vs2003, windows系统; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077     TITLE    ./main.cpp    .386Pinclude listing.incif Version gt 510.model FLATelse_TEXT    SEGMENT PARA USE32 PUBLIC CODE_TEXT    ENDS_DATA    SEGMENT DWORD USE32 PUBLIC DATA_DATA    ENDSCONST    SEGMENT DWORD USE32 PUBLIC CONSTCONST    ENDS_BSS    SEGMENT DWORD 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 ??0AQAEXZ_TEXT    SEGMENT PARA USE32 PUBLIC CODE_TEXT    ENDS;    COMDAT ??0AQAEABV0Z_TEXT    SEGMENT PARA USE32 PUBLIC CODE_TEXT    ENDS;    COMDAT ?funbyValueYA?AVAV1Z_TEXT    SEGMENT PARA USE32 PUBLIC CODE_TEXT    ENDS;    COMDAT _main_TEXT    SEGMENT PARA USE32 PUBLIC CODE_TEXT    ENDSsxdata    SEGMENT DWORD USE32 SXDATAsxdata    ENDSFLAT    GROUP _DATA, CONST, _BSS    ASSUME    CS: FLAT, DS: FLAT, SS: FLATendifINCLUDELIB LIBCDINCLUDELIB OLDNAMESPUBLIC    ??0AQAEABV0Z                ; A::APUBLIC    ?funbyValueYA?AVAV1Z            ; funbyValueEXTRN    __RTC_InitBase:NEAREXTRN    __RTC_Shutdown:NEAREXTRN    __RTC_CheckEsp:NEAR;    COMDAT rtc$IMZ; File j:/example/contructor/main.cpprtc$IMZ    SEGMENT__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBasertc$IMZ    ENDS;    COMDAT rtc$TMZrtc$TMZ    SEGMENT__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown; Function compile flags: /Odt /RTCsu /ZIrtc$TMZ    ENDS;    COMDAT ?funbyValueYA?AVAV1Z_TEXT    SEGMENT___$ReturnUdt$ 8                    ; size 4_c$ 12                        ; size 4?funbyValueYA?AVAV1Z PROC NEAR            ; funbyValue, COMDAT; 19   : {  00000    55         push     ebp  00001    8b ec         mov     ebp, esp  00003    81 ec c0 00 00    00         sub     esp, 192        ; 000000c0H  00009    53         push     ebx  0000a    56         push     esi  0000b    57         push     edi  0000c    8d bd 40 ff ff    ff         lea     edi, DWORD PTR [ebp-192]  00012    b9 30 00 00 00     mov     ecx, 48            ; 00000030H  00017    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH  0001c    f3 ab         rep stosd; 20   :     return c;  0001e    8d 45 0c     lea     eax, DWORD PTR _c$[ebp]  00021    50         push     eax  00022    8b 4d 08     mov     ecx, DWORD PTR ___$ReturnUdt$[ebp]  00025    e8 00 00 00 00     call     ??0AQAEABV0Z    ; A::A  0002a    8b 45 08     mov     eax, DWORD PTR ___$ReturnUdt$[ebp]; 21   : }  0002d    5f         pop     edi  0002e    5e         pop     esi  0002f    5b         pop     ebx  00030    81 c4 c0 00 00    00         add     esp, 192        ; 000000c0H  00036    3b ec         cmp     ebp, esp  00038    e8 00 00 00 00     call     __RTC_CheckEsp  0003d    8b e5         mov     esp, ebp  0003f    5d         pop     ebp  00040    c3         ret     0?funbyValueYA?AVAV1Z ENDP                ; funbyValue; Function compile flags: /Odt /RTCsu /ZI_TEXT    ENDS;    COMDAT ??0AQAEABV0Z_TEXT    SEGMENT_this$ -8                        ; size 4_c$ 8                            ; size 4??0AQAEABV0Z PROC NEAR                ; A::A, COMDAT; _this$ ecx; 9    :     A(const A 000000ccH  00009    53         push     ebx  0000a    56         push     esi  0000b    57         push     edi  0000c    51         push     ecx  0000d    8d bd 34 ff ff    ff         lea     edi, DWORD PTR [ebp-204]  00013    b9 33 00 00 00     mov     ecx, 51            ; 00000033H  00018    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH  0001d    f3 ab         rep stosd  0001f    59         pop     ecx  00020    89 4d f8     mov     DWORD PTR _this$[ebp], ecx; 10   :     {; 11   :        i c.i;  00023    8b 45 f8     mov     eax, DWORD PTR _this$[ebp]  00026    8b 4d 08     mov     ecx, DWORD PTR _c$[ebp]  00029    8b 11         mov     edx, DWORD PTR [ecx]  0002b    89 10         mov     DWORD PTR [eax], edx; 12   :     }  0002d    8b 45 f8     mov     eax, DWORD PTR _this$[ebp]  00030    5f         pop     edi  00031    5e         pop     esi  00032    5b         pop     ebx  00033    8b e5         mov     esp, ebp  00035    5d         pop     ebp  00036    c2 04 00     ret     4??0AQAEABV0Z ENDP                    ; A::A_TEXT    ENDSPUBLIC    ??0AQAEXZ                    ; A::APUBLIC    _mainEXTRN    _RTC_CheckStackVars8:NEAR; Function compile flags: /Odt /RTCsu /ZI;    COMDAT _main_TEXT    SEGMENT$T315 -212                        ; size 4_b$ -8                        ; size 4_argc$ 8                        ; size 4_argv$ 12                        ; size 4_main    PROC NEAR                    ; COMDAT; 24   : {  00000    55         push     ebp  00001    8b ec         mov     ebp, esp  00003    81 ec e4 00 00    00         sub     esp, 228        ; 000000e4H  00009    53         push     ebx  0000a    56         push     esi  0000b    57         push     edi  0000c    8d bd 1c ff ff    ff         lea     edi, DWORD PTR [ebp-228]  00012    b9 39 00 00 00     mov     ecx, 57            ; 00000039H  00017    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH  0001c    f3 ab         rep stosd; 25   :    A b;  0001e    8d 4d f8     lea     ecx, DWORD PTR _b$[ebp]  00021    e8 00 00 00 00     call     ??0AQAEXZ        ; A::A; 26   :    funbyValue(b);  00026    51         push     ecx  00027    8b cc         mov     ecx, esp  00029    8d 45 f8     lea     eax, DWORD PTR _b$[ebp]  0002c    50         push     eax  0002d    e8 00 00 00 00     call     ??0AQAEABV0Z    ; A::A  00032    8d 8d 2c ff ff    ff         lea     ecx, DWORD PTR $T315[ebp]  00038    51         push     ecx  00039    e8 00 00 00 00     call     ?funbyValueYA?AVAV1Z ; funbyValue  0003e    83 c4 08     add     esp, 8; 27   : }  00041    33 c0         xor     eax, eax  00043    52         push     edx  00044    8b cd         mov     ecx, ebp  00046    50         push     eax  00047    8d 15 00 00 00    00         lea     edx, DWORD PTR $L318  0004d    e8 00 00 00 00     call     _RTC_CheckStackVars8  00052    58         pop     eax  00053    5a         pop     edx  00054    5f         pop     edi  00055    5e         pop     esi  00056    5b         pop     ebx  00057    81 c4 e4 00 00    00         add     esp, 228        ; 000000e4H  0005d    3b ec         cmp     ebp, esp  0005f    e8 00 00 00 00     call     __RTC_CheckEsp  00064    8b e5         mov     esp, ebp  00066    5d         pop     ebp  00067    c3         ret     0$L318:  00068    01 00 00 00     DD     1  0006c    00 00 00 00     DD     $L317$L317:  00070    f8 ff ff ff     DD     -8            ; fffffff8H  00074    04 00 00 00     DD     4  00078    00 00 00 00     DD     $L316$L316:  0007c    62         DB     98            ; 00000062H  0007d    00         DB     0_main    ENDP; Function compile flags: /Odt /RTCsu /ZI_TEXT    ENDS;    COMDAT ??0AQAEXZ_TEXT    SEGMENT_this$ -8                        ; size 4??0AQAEXZ PROC NEAR                    ; A::A, COMDAT; _this$ ecx; 4    :     A()  00000    55         push     ebp  00001    8b ec         mov     ebp, esp  00003    81 ec cc 00 00    00         sub     esp, 204        ; 000000ccH  00009    53         push     ebx  0000a    56         push     esi  0000b    57         push     edi  0000c    51         push     ecx  0000d    8d bd 34 ff ff    ff         lea     edi, DWORD PTR [ebp-204]  00013    b9 33 00 00 00     mov     ecx, 51            ; 00000033H  00018    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH  0001d    f3 ab         rep stosd  0001f    59         pop     ecx  00020    89 4d f8     mov     DWORD PTR _this$[ebp], ecx; 5    :     {; 6    :         i 0;  00023    8b 45 f8     mov     eax, DWORD PTR _this$[ebp]  00026    c7 00 00 00 00    00         mov     DWORD PTR [eax], 0; 7    :     }  0002c    8b 45 f8     mov     eax, DWORD PTR _this$[ebp]  0002f    5f         pop     edi  00030    5e         pop     esi  00031    5b         pop     ebx  00032    8b e5         mov     esp, ebp  00034    5d         pop     ebp  00035    c3         ret     0??0AQAEXZ ENDP                    ; A::A_TEXT    ENDSEND总结从程序相应的汇编中我们可以看到 funbyValue中参数和返回值的内存都是分配在调用函数中分析由粗线部分我们可以知道类对象的this指针地址值放到寄存器ecx中在类对象的方法中我们可以看到ecx中的地址值被复制到方法的堆栈中然后对this指向对象中其他成员的方法。由红色粗斜线部分我们可以知道类对象的成员方法中参数是用户定义类型并且是传递引用的情况下是通过压栈的方法传入的。    在函数参数和返回值都是用户自定义的类型时并且是传值的情况下他们都是在调用者的空间中进行分配的1对于参数则是在栈顶分配的理由是它将esp作为this指针并且通过拷贝构造函数将实参数的值拷贝到形参中这可以由兰粗部分的汇编代码看出。2而对于返回值它是调用者的堆栈内部进行分配的并且通过压栈的方式进入到堆栈中这可以由粉红部分得知。这里还有一个规律那就是每个函数内部都是用ebp来表示它可用堆栈内存的起始部分esp减去一定的空间这样esp是那个函数可以分配局部变量的堆栈的末尾。C中的参数和返回值的类型的选择引用参数指针参数值类型参数对于数据类型来说他就是指针类型参数。
上一篇:javascript–使用mongoose在MongoDB中批量插入
下一篇:没有了
网友评论