C++中

    技术2022-05-19  40

    首先,我们要学会在Visual Studio 2008中学会查看C++代码对应的汇编代码。

    给程序添加断点并开始调试程序后,对文件中间右键=》转到反汇编,即可看到汇编代码。

     

    汇编代码用//注释,说明用/**/注释,分别使用基本数据类型、数组、指针、引用四种数据类型的参数进行比较,代码如下:

    #include <iostream> using namespace std; /*C,C++ default style **arguments passing order: from right to left **who clean stack: caller function*/ void __cdecl Cdecl(int a, int b[], int *c, int &d) { cout << endl; cout << a++ << "/t" << b << "/t" << c << "/t" << d++ << "/t" << endl; for(int i = 0; i < 3; i ++) { cout << b[i]++ << "/t"; } cout << endl; cout << "hello cdecl" << endl; } /*PASCAL,CALLBACK,Win32 API style **arguments passing order: from right to left **who clean stack: callee function*/ void __stdcall Stdcall(int a, int b[], int *c, int &d) { cout << endl; cout << a++ << "/t" << b << "/t" << c << "/t" << d++ << "/t" << endl; for(int i = 0; i < 3; i ++) { cout << b[i]++ << "/t"; } cout << endl; cout << "hello stdcall" << endl; } //0041175A pop edi //0041175B pop esi //0041175C pop ebx //0041175D add esp,0C8h //00411763 cmp ebp,esp //00411765 call @ILT+440(__RTC_CheckEsp) (4111BDh) //0041176A mov esp,ebp //0041176C pop ebp //0041176D ret 10h //clean the stack /*A fast call style **arguments passing order: from right to left **who clean stack: callee function*/ void __fastcall Fastcall(int a, int b[], int *c, int &d) { cout << endl; cout << a++ << "/t" << b << "/t" << c << "/t" << d++ << "/t" << endl; for(int i = 0; i < 3; i ++) { cout << b[i]++ << "/t"; } cout << endl; cout << "hello fastcall" << endl; } //004118D2 pop edi //004118D3 pop esi //004118D4 pop ebx //004118D5 add esp,0E0h //004118DB cmp ebp,esp //004118DD call @ILT+440(__RTC_CheckEsp) (4111BDh) //004118E2 mov esp,ebp //004118E4 pop ebp //004118E5 ret 8 //clean the stack class E { public: int m_e; //member variable static int m_s; //static variable E(int e) { m_e = e; } /*static function invoke, just like the __cdecl style **note: You can add the modifier __thiscall before the static function name, but you cannot force the program pass THIS Pointer to static function **arguments passing order: from right to left **who clean stack: caller function*/ static void Staticcall(int a, int b[], int *c, int &d) { cout << endl; m_s ++; cout << a++ << "/t" << b << "/t" << c << "/t" << d++ << "/t" << endl; for(int i = 0; i < 3; i ++) { cout << b[i]++ << "/t"; } cout << endl; cout << "hello staticcall" << endl; } //00412284 pop edi //00412285 pop esi //00412286 pop ebx //00412287 add esp,0DCh //0041228D cmp ebp,esp //0041228F call @ILT+460(__RTC_CheckEsp) (4111D1h) //00412294 mov esp,ebp //00412296 pop ebp //00412297 ret /*(Only for) C++ member functions default style, ECX register contains THIS Pointer secretly **note: You can change the modifier to __cdecl or another to change the arguments passing style or who clean stack responsibility, but you cannot stopping THIS Pointer passing **arguments passing order: from right to left **who clean stack: callee function*/ void __thiscall Thiscall(int a, int b[], int *c, int &d) { cout << endl; cout << a++ << "/t" << b << "/t" << c << "/t" << d++ << "/t" << endl; for(int i = 0; i < 3; i ++) { cout << b[i]++ << "/t"; } cout << endl; cout << "hello thiscall" << endl; } //00411CDF pop edi //00411CE0 pop esi //00411CE1 pop ebx //00411CE2 add esp,0D4h //00411CE8 cmp ebp,esp //00411CEA call @ILT+445(__RTC_CheckEsp) (4111C2h) //00411CEF mov esp,ebp //00411CF1 pop ebp //00411CF2 ret 10h }; int E::m_s = 0; //Initial static variable, it cannot be initialed in the class, only if it's a const value int main(int argc, char *argv[]) { //data int a = 1; //sample data int b[] = {1,2,3}; //array int *c = (int *)malloc(sizeof(int)); //pointer int d = 2; //for inference E e1(1), e2(2); //for member/static function cout << &e1 << "/t" << &e2 << endl; printf("%p/t%p/n", &e1.m_e, &e2.m_e); printf("%p/t%p/n", &E::Thiscall, &E::Staticcall); cout << &E::Thiscall << "/t" << &E::Staticcall << endl; cout << &e1.m_s << "/t" << &e2.m_s << "/t" << &E::m_s << "/t" << E::m_s << endl; cout << "hello main" << endl; Cdecl(a, b, c, d); //00411838 lea eax,[d] //actually pass the address of the data //0041183B push eax //0041183C mov ecx,dword ptr [c] //0041183F push ecx //00411840 lea edx,[b] //00411843 push edx //00411844 mov eax,dword ptr [a] //00411847 push eax //00411848 call Cdecl (411032h) //0041184D add esp,10h //clean the stack Stdcall(a, b, c, d); //00411A6F lea eax,[d] //00411A72 push eax //00411A73 mov ecx,dword ptr [c] //00411A76 push ecx //00411A77 lea edx,[b] //00411A7A push edx //00411A7B mov eax,dword ptr [a] //00411A7E push eax //00411A7F call Stdcall (41103Ch) Fastcall(a, b, c, d); //00411A84 lea eax,[d] //00411A87 push eax //00411A88 mov ecx,dword ptr [c] //00411A8B push ecx //00411A8C lea edx,[b] //00411A8F mov ecx,dword ptr [a] //use two registers to pass the last two arguments(so called "fastcall") //00411A92 call Fastcall (4110DCh) e1.Thiscall(a, b, c, d); //00411AD2 lea eax,[d] //00411AD5 push eax //00411AD6 mov ecx,dword ptr [c] //00411AD9 push ecx //00411ADA lea edx,[b] //00411ADD push edx //00411ADE mov eax,dword ptr [a] //00411AE1 push eax //00411AE2 lea ecx,[e] //a secret extra parameter //00411AE5 call E::Thiscall (41105Fh) E::Staticcall(a, b, c, d); //00411B04 lea eax,[d] //00411B07 push eax //00411B08 mov ecx,dword ptr [c] //00411B0B push ecx //00411B0C lea edx,[b] //00411B0F push edx //00411B10 mov eax,dword ptr [a] //00411B13 push eax //00411B14 call E::Staticcall (4110A5h) //00411B19 add esp,10h //clean the stack return 0; }

     

    总结


    最新回复(0)