VC函数调用的汇编代码
来源:优易学  2011-12-9 10:20:26   【优易学:中国教育考试门户网】   资料下载   IT书店

  //下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道
  __asm
  {
  mov dword ptr [ebp-4], 20h
  }
  int b = i;
  cout << "i=" << b << endl;
  ChangNum(50, 100);
  return 0;
  }
  int ChangNum(int nParam, int nW)
  {
  int i = 10;
  int a = i;
  cout << "i=" << a << endl;
  __asm
  {
  mov dword ptr [ebp - 4], 20h
  mov dword ptr [ebp + 12], 0h
  }
  int b = i;
  cout << "i=" << b << endl;
  return 0;
  }
  主要看看函数调用那段的汇编代码:
  1、函数调用点汇编代码:
  23: ChangNum(50, 100);
  00401824 push 64h
  00401826 push 32h
  00401828 call @ILT+590(ChangNum) (00401253)
  0040182D add esp,8
  分别是两个参数入栈,call这句有两个作用,下一行地址入栈,同时进行函数调用,最后一句是恢复栈空间,两个整型参数每个四字节,所以esp堆栈指针要加上8字节。
  2、函数体中的汇编代码:
  004018C0 push ebp
  004018C1 mov ebp,esp
  004018C3 sub esp,4Ch
  004018C6 push ebx
  004018C7 push esi
  004018C8 push edi
  004018C9 lea edi,[ebp-4Ch]
  004018CC mov ecx,13h
  004018D1 mov eax,0CCCCCCCCh
  004018D6 rep stos dword ptr [edi]
  30: int i = 10;
  004018D8 mov dword ptr [ebp-4],0Ah
  31: int a = i;
  004018DF mov eax,dword ptr [ebp-4]
  004018E2 mov dword ptr [ebp-8],eax
  32: cout << "i=" << a << endl;
  004018E5 push offset @ILT+195(std::endl) (004010c8)
  004018EA mov ecx,dword ptr [ebp-8]
  004018ED push ecx
  004018EE push offset string "i=" (0046c01c)
  004018F3 push offset std::cout (00477a10)
  004018F8 call @ILT+645(std::operator<<) (0040128a)
  004018FD add esp,8
  00401900 mov ecx,eax
  00401902 call @ILT+250(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004010ff)
  00401907 mov ecx,eax
  00401909 call @ILT+475(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011e0)
  33:
  34: __asm
  35: {
  36: mov dword ptr [ebp - 4], 20h
  0040190E mov dword ptr [ebp-4],20h
  37: mov dword ptr [ebp + 12], 0h
  00401915 mov dword ptr [ebp+0Ch],0
  38: }
  39: int b = i;
  0040191C mov edx,dword ptr [ebp-4]
  0040191F mov dword ptr [ebp-0Ch],edx
  40: cout << "i=" << b << endl;
  00401922 push offset @ILT+195(std::endl) (004010c8)
  00401927 mov eax,dword ptr [ebp-0Ch]
  0040192A push eax
  0040192B push offset string "i=" (0046c01c)
  00401930 push offset std::cout (00477a10)
  00401935 call @ILT+645(std::operator<<) (0040128a)
  0040193A add esp,8
  0040193D mov ecx,eax
  0040193F call @ILT+250(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004010ff)
  00401944 mov ecx,eax
  00401946 call @ILT+475(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011e0)
  41:
  42: return 0;
  0040194B xor eax,eax
  43: }
  0040194D pop edi
  0040194E pop esi
  0040194F pop ebx
  00401950 add esp,4Ch
  00401953 cmp ebp,esp
  00401955 call __chkesp (00406df0)
  0040195A mov esp,ebp
  0040195C pop ebp
  0040195D ret
  ebp入栈,然后将esp的值传给ebp,现在ebp是指向此时的堆栈了,注意后面除了函数返回前,ebp的值一直是固定的,通过这种机制来访问参数和局部变量,esp减少了一个比较大的值,留给局部变量使用的,然后是通用寄存器入栈,接着就是实际的工作的代码了,这里就不说了,到那个return后面再看,是通用寄存器出栈,esp恢复,ebp出栈,ret回到函数调用的下一条指令。

上一页  [1] [2] 

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训