当前位置:首页
开发技术指南» 文章正文
    引言:

    摘要: 局部变量的销毁是什么含义呢?是函数返回,局部变量的内存就被清零了还是因为恢复现场而被写入别的值?可是印象中,函数返回只是栈顶指针改变了而已,不记得有说过对栈内存的其他操作啊,不解! =============================================== #include <stdio.h> void __stdcall func(int param1,i......
 ·如何在c++中得到当前时间    »显示摘要«
    摘要: 用哪个函数?得到结果的格式是什么? ......


$$$谁给我讲解一下局部变量在函数返回之后就被销毁的具体含义

局部变量的销毁是什么含义呢?是函数返回,局部变量的内存就被清零了还是因为恢复现场而被写入别的值?可是印象中,函数返回只是栈顶指针改变了而已,不记得有说过对栈内存的其他操作啊,不解!  
  ===============================================  
  #include   <stdio.h>  
   
  void   __stdcall   func(int   param1,int   param2,int   param3)  
  {  
  int   var1=param1;  
  int   var2=param2;  
  int   var3=param3;  
  printf("0x%08x\n",&para;m1);   //打印出各个变量的内存地址  
  printf("0x%08x\n",&para;m2);  
  printf("0x%08x\n\n",&para;m3);  
  printf("0x%08x\n",&var1);  
  printf("0x%08x\n",&var2);  
  printf("0x%08x\n\n",&var3);  
  return;  
  }  
   
  int   main()  
  {  
  func(1,2,3);  
  return   0;  
  }  
   
  编译后的执行结果是:  
   
  0x0012ff78  
  0x0012ff7c  
  0x0012ff80  
   
  0x0012ff68  
  0x0012ff6c  
  0x0012ff70  
   
   
   
  ├———————┤<—函数执行时的栈顶、低端内存区域  
  │   ……   │  
  ├———————┤  
  │   var   1   │  
  ├———————┤  
  │   var   2   │  
  ├———————┤  
  │   var   3   │  
  ├———————┤  
  │   RET   │  
  ├———————┤<—“__cdecl”函数返回后的栈顶  
  │   parameter   1   │  
  ├———————┤  
  │   parameter   2   │  
  ├———————┤  
  │   parameter   3   │  
  ├———————┤<—“__stdcall”函数返回后的栈顶  
  │   ……   │  
  ├———————┤<—栈底、高端内存区域  
  上图就是函数调用过程中堆栈的样子了。首先,三个参数以从又到左的次序压入堆栈,先压“param3”,再压“param2”,最后压入“param1”;然后压入函数的返回地址(RET),接着跳转到函数地址接着执行;第三步,将栈顶(ESP)减去一个数,为本地变量分配内存空间,上例中是减去12字节(ESP=ESP-3*4,每个int变量占用4个字节);接着就初始化本地变量的内存空间。由于“__stdcall”调用由被调函数调整堆栈,所以在函数返回前要恢复堆栈,先回收本地变量占用的内存(ESP=ESP+3*4),然后取出返回地址,填入EIP寄存器,回收先前压入参数占用的内存(ESP=ESP+3*4),继续执行调用者的代码。参见下列汇编代码:  
   
  ;--------------func   函数的汇编代码-------------------  
   
  :00401000   83EC0C   sub   esp,   0000000C   //创建本地变量的内存空间  
  :00401003   8B442410   mov   eax,   dword   ptr   [esp+10]  
  :00401007   8B4C2414   mov   ecx,   dword   ptr   [esp+14]  
  :0040100B   8B542418   mov   edx,   dword   ptr   [esp+18]  
  :0040100F   89442400   mov   dword   ptr   [esp],   eax  
  :00401013   8D442410   lea   eax,   dword   ptr   [esp+10]  
  :00401017   894C2404   mov   dword   ptr   [esp+04],   ecx  
   
  ……………………  
   
  :00401075   83C43C   add   esp,   0000003C   ;恢复堆栈,回收本地变量的内存空间  
  :00401078   C3   ret   000C   ;函数返回,恢复参数占用的内存空间  
  ;如果是“__cdecl”的话,这里是“ret”,堆栈将由调用者恢复  
   
  ;-------------------函数结束-------------------------  
   
   
  ;--------------主程序调用func函数的代码--------------  
   
  :00401080   6A03   push   00000003   //压入参数param3  
  :00401082   6A02   push   00000002   //压入参数param2  
  :00401084   6A01   push   00000001   //压入参数param1  
  :00401086   E875FFFFFF   call   00401000   //调用func函数  
  ;如果是“__cdecl”的话,将在这里恢复堆栈,“add   esp,   0000000C”  
  ======================================================================================  
   
   
  在这个例子中,难道函数返回了之后,VAR3所在的内存的内容就被改变了吗?没见到有相应的指令代码啊。那这个局部变量在返回之后就被销毁具体是什么意思呢?

NO.1   作者: tomsx

无法回答你,看了你写的东西又学了不少东西  
   
  帮我推荐一本书吧,汇编的,主要讲原理多一些,有建议吗?谢谢

NO.2   作者: firstrose

刚刚返回时,内存暂时没有改变。  
   
  这个销毁,实际是指相应的内存区域不再受当前程序控制。  
   
  你仍然可以访问对应的地址,但是里面的值很快会被覆盖,也可能不会被覆盖。  
   
  注意,我说的是地址,不是变量。

NO.3   作者: VxD1

局部变量是分配在堆栈中的,刚进入函数分配局部变量时是对sp进行修改,使其留出一些堆栈空间来存放局部变量,当函数返回时再对sp进行修改,使其恢复到原先未修改的状态.  
  函数返回后,局部变量的值无意义

NO.4   作者: zhang_jiang

Linux一般字符串都放在.rodata,   你可以通过.c生成.s文件来看.


    摘要: 大家能简单说说吗? char char * string array 的区别,谢谢。 为何 char str[50];或char *str[50]; cout << sizeof(str); 一个是50,一个是200啊。 ......
» 本期热门文章:

©2000-2007 All Rights Reserved. 最佳浏览:1024X768 MSIE