首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

懂C++和汇编的朋友进,该怎么处理

2012-02-26 
懂C++和汇编的朋友进参数传递的过程不是很明白我们还没学到汇编语言,看的不是很明白麻烦大家解释下汇编代

懂C++和汇编的朋友进
参数传递的过程不是很明白
我们还没学到汇编语言,看的不是很明白
麻烦大家解释下汇编代码,谢谢大家!

C/C++ code
//C++代码:#include<iostream>using namespace std;class A{public:    A(int x = 0) : a(x){cout<<"normal"<<endl;}    A(const A &ref) : a(ref.a){cout<<"copy"<<endl;}    int a;};void test(A x){}int main(){    A a;    test(a);    system("pause");    return 0;}

Assembly code
//汇编代码:17:   int main()18:   {004011B0   push        ebp004011B1   mov         ebp,esp004011B3   sub         esp,48h004011B6   push        ebx004011B7   push        esi004011B8   push        edi004011B9   lea         edi,[ebp-48h]004011BC   mov         ecx,12h004011C1   mov         eax,0CCCCCCCCh004011C6   rep stos    dword ptr [edi]19:       A a;004011C8   push        0004011CA   lea         ecx,[ebp-4]                //ecx传递this指针?004011CD   call        @ILT+10(A::A) (0040100f)   //构造局部对象a20:21:       test(a);004011D2   push        ecx                        //传递拷贝构造函数的引用参数 即对象a的地址004011D3   mov         ecx,esp                    //这条语句是干嘛的? 为形参分配空间?004011D5   lea         eax,[ebp-4]004011D8   push        eax                        //这条语句的作用是什么? 构造形参的话this指针有了,参数也有了,怎么此处又将a的地址入栈? 004011D9   call        @ILT+150(A::A) (0040109b)  //在ecx指向的空间以已经压栈的a的地址做引用参数拷贝构造形参?004011DE   call        @ILT+180(test) (004010b9)  //004011E3   add         esp,422:       system("pause");004011E6   push        offset string "pause" (0043101c)004011EB   call        system (00409140)004011F0   add         esp,423:       return 0;004011F3   xor         eax,eax24:   }13:   void test(A x)14:   {00401180   push        ebp00401181   mov         ebp,esp00401183   sub         esp,40h00401186   push        ebx00401187   push        esi00401188   push        edi00401189   lea         edi,[ebp-40h]0040118C   mov         ecx,10h00401191   mov         eax,0CCCCCCCCh00401196   rep stos    dword ptr [edi]15:   }00401198   pop         edi00401199   pop         esi0040119A   pop         ebx0040119B   mov         esp,ebp0040119D   pop         ebp0040119E   ret


[解决办法]
现在赶快亡羊补牢还来得及
[解决办法]
自己注释了那么多了,也差不多了吧
[解决办法]
汇编。。。不懂。。曾经就很厌恶这门科,,想当年差点挂科。。杯具
[解决办法]
汇编。。。不懂。。曾经就很厌恶这门科,,想当年差点挂科。。杯具
[解决办法]
不是很懂,C到汇编还好说点,C++就更晕了
[解决办法]
Assembly code
 
19:    A a;
004011C8  push    0              ;实际要调用A(int x = 0)这个构造函数,
                        ;这个是默认参数入栈
004011CA  lea    ecx,[ebp-4]        ;将a对象的地址存入ecx,vc一般this存入ecx
      ;gcc中this作为最后一参数入栈的,显然ebp-4 ~ebp这段空间就是a的存储空间
004011CD  call    @ILT+10(A::A) (0040100f)  //构造局部对象a
20:
21:    test(a);
004011D2  push    ecx            ;将ecx入栈保存
004011D3  mov    ecx,esp          ;将esp保存到ecx,说明编译器打算将esp-4~esp
    ;作为test函数中参数a对应的内存,test传参时要调用A的拷贝构造函数生成一个临时对象


004011D5  lea    eax,[ebp-4];将a的地址保存eax
004011D8  push    eax            ;a作为参数入栈,调用A的拷贝构造函数,
                      ;在esp-4~esp处生成一个临时对象
004011D9  call    @ILT+150(A::A) (0040109b) 
004011DE  call    @ILT+180(test) (004010b9)  ;由于在上个栈帧顶端esp-4~esp已经生成了一个
              ;一个临时对象a,所以省去了push操作,直接调用test函数
004011E3  add    esp,4
22:    system("pause");
004011E6  push    offset string "pause" (0043101c)
004011EB  call    system (00409140)
004011F0  add    esp,4
23:    return 0;
004011F3  xor    eax,eax
24:  }


[解决办法]
1. 004011D3 mov ecx,esp //这条语句是干嘛的? 为形参分配空间?

ecx = esp,保留esp,待函数调用完再恢复,因为函数调用中肯定会用到esp.

2. 004011D5 lea eax,[ebp-4]
004011D8 push eax //这条语句的作用是什么? 构造形参的话this指针有了,参数也有了,怎么此处又将a的地址入栈?

这两个语句应该是给参数a分配栈空间。

供参考
[解决办法]
早忘了,帮顶

[解决办法]
楼上解释的不错了,test的函数参数是A对象,不是引用,所以会在test的函数调用的栈上生成一个A对象,调用拷贝构造函数。 这里A的大小是4字节,所以esp栈指针是减4的,函数返回时会看到add esp 4。

你可以看看深入探索c++对象模型这本书,编译器在传递对象时候如何在栈上构造对象,还有一些返回值的。这本书不错,虽然没有用汇编代码解释,但已经很清楚了。其实汇编代码也是各种编译器生成的。
[解决办法]
我上面说的是10楼解释的不错。

另外,你12楼说的,两个地址是不一样的。ecx是原来的a的地址,eax是test函数的栈上为A分配的临时对象的地址。
[解决办法]
不错,这么早就研究汇编了。
[解决办法]
浪费时间的吧
[解决办法]
楼主现在大一?
[解决办法]
看看吧..
[解决办法]
探讨

引用:
楼主现在大一?

恩,
马上就要大二了

[解决办法]
早忘到九霄云外了,帮顶一下...
[解决办法]
Assembly code
13:   void test(A x)14:   {00401180   push        ebp00401181   mov         ebp,esp00401183   sub         esp,40h00401186   push        ebx00401187   push        esi00401188   push        edi00401189   lea         edi,[ebp-40h]0040118C   mov         ecx,10h00401191   mov         eax,0CCCCCCCCh00401196   rep stos    dword ptr [edi]15:   }00401198   pop         edi00401199   pop         esi0040119A   pop         ebx0040119B   mov         esp,ebp0040119D   pop         ebp0040119E   ret19:       A a;004011C8   push        0                          ;实际要调用A(int x = 0)这个构造函数,                                                  ;这个是默认参数入栈004011CA   lea         ecx,[ebp-4]                ;将a对象的地址存入ecx,vc一般this存入ecx                                                  ;gcc中this作为最后一个参数入栈,显然ebp-4 ~ebp-1这段空间就是a的存储空间004011CD   call        @ILT+10(A::A) (0040100f)   ;构造局部变量a20:21:       test(a);004011D2   push        ecx                        ;将ecx入栈保存004011D3   mov         ecx,esp                    ;将esp保存到ecx,调用构造函数隐式传入的this的值保存在ecx里,此时this=esp,说明编译器打算将esp~esp+3,                                                  ;作为test传参时调用A的拷贝构造函数生成一个临时对象的存储空间,                          ;也就是说esp~esp+3保存由于test函数调用产生的临时对象004011D5   lea         eax,[ebp-4]                ;将a的地址保存eax,由于生成临时对象调用的A(const A &ref)是传的引用,                                                  ;所以把a的对象地址压入栈中,作为A(const A &ref)参数,从这也可以看出引用在底层实现和指针差不多004011D8   push        eax                                                                         004011D9   call        @ILT+150(A::A) (0040109b)  ;用来生成临时对象,调用A(const A &ref)在esp~esp+3处生成临时对象。004011DE   call        @ILT+180(test) (004010b9)  ;由于类成员函数是thiscall调用约定,自己清理栈,所以A(const A &ref)调用完毕,                                                  ;上面eax会出栈,此时栈顶就是临时对象的存在空间。                          ;调用test函数时,保证是从test对应的栈帧的ebp+4位置访问临时变量的,此时访问的应该是生成的临时对象的空间的004011E3   add         esp,422:       system("pause");004011E6   push        offset string "pause" (0043101c)004011EB   call        system (00409140)004011F0   add         esp,423:       return 0;004011F3   xor         eax,eax24:   } 


[解决办法]
004011D2 push ecx ;将ecx入栈保存
这条指令跟拷贝构造函数调用没啥关系,因为下面ecx被修改了,这条指令只是保存修改之前的ecx的值。
在vc下,成员函数调用参数从右到左入栈,this存入ecx。
push eax;才是参数入栈, mov ecx,esp 则是保存this指针

[解决办法]
注释那么多,应该全懂了吧
[解决办法]
是有错误
[解决办法]
回复有风险,接分须谨慎!
[解决办法]

探讨

引用:
004011D2 push ecx ;将ecx入栈保存
这条指令跟拷贝构造函数调用没啥关系,因为下面ecx被修改了,这条指令只是保存修改之前的ecx的值。
在vc下,成员函数调用参数从右到左入栈,this存入ecx。
push eax;才是参数入栈, mov ecx,esp 则是保存this指针

呵呵
多谢你了
不过我觉得此……

热点排行
Bad Request.