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

  主要谈谈vc里面函数调用汇编成汇编代码的情形,首先针对之前的一个小程序,说说vc编译器的优化。
  例子程序:
  #include <iostream>
  using namespace std;
  int main(int argc, char* argv[])
  {
  int i=10;
  int a = i;
  cout << "i=" << a << endl;
  //下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道
  __asm
  {
  mov dword ptr [ebp-4], 20h
  }
  int b = i;
  cout << "i=" << b << endl;
  return 0;
  }
  这段代码很简洁,但汇编代码可不简洁,青年人网提看看release模式下的汇编代码概况:
  ……
  ; 14 :
  ; 15 : //下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道
  ; 16 : __asm
  ; 17 : {
  ; 18 : mov dword ptr [ebp-4], 20h
  mov DWORD PTR [ebp-4], 32 ; 00000020H
  ; 19 : }
  ; 20 : int b = i;
  ; 21 : cout << "i=" << b << endl;
  push 10 ; 0000000aH
  push OFFSET FLAT:??_C@_02HDOK@i?$DN?$AA@ ; `string’
  push OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout
  call ??6std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<
  add esp, 8
  mov ecx, eax
  call ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
  mov esi, eax
  push 10 ; 0000000aH
  mov ecx, esi
  call ?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char> >::put
  mov ecx, DWORD PTR [esi]
  xor edi, edi
  ……
  调用cout前面,直接一个push 10,这是函数调用前压参数的过程,压了个常数在里面,呵呵,其实i已经被修改了,青年人网提示编译器不知道,以为i仍然是10,顾做了优化,压参压了常量在里面。
  再看看debug模式下的汇编代码情况:
  16: __asm
  17: {
  18: mov dword ptr [ebp-4], 20h
  004017DE mov dword ptr [ebp-4],20h
  19: }
  20: int b = i;
  004017E5 mov edx,dword ptr [ebp-4]
  004017E8 mov dword ptr [ebp-0Ch],edx
  21: cout << "i=" << b << endl;
  004017EB push offset @ILT+195(std::endl) (004010c8)
  004017F0 mov eax,dword ptr [ebp-0Ch]
  004017F3 push eax
  004017F4 push offset string "i=" (0046c01c)
  004017F9 push offset std::cout (00477a10)
  004017FE call @ILT+640(std::operator<<) (00401285)
  00401803 add esp,8
  00401806 mov ecx,eax
  b = i,赋值这句成了从i的地址去取值送往b了,
  mov edx,dword ptr [ebp-4]
  mov dword ptr [ebp-0Ch],edx
  注意release版本是没有这两句的,所以现在b取值就是肯定正确的了,后面压参的时候,也把b地址指向的值压入了堆栈,呵呵,这也是之前说的为什么两个版本下运行结果不同的原因。
  把这个程序稍加修改,开始我们下面的函数调用汇编浅析:
  #include <iostream>
  using namespace std;
  int ChangNum(int, int);
  int main(int argc, char* argv[])
  {
  int i=10;
  int a = i;
  cout << "i=" << a << endl;

[1] [2] 下一页

责任编辑:小草

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