免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1392 | 回复: 0
打印 上一主题 下一主题

编译器生成的new[]代码,如何解读? 比我想象的要复杂,讨论一下! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-06-01 22:06 |只看该作者 |倒序浏览
本帖最后由 songweibo 于 2012-06-02 10:45 编辑

<<深入理解C++内存对象模型>>这本书里面说到,编译器为形如

  1. struct s;
  2. s* ps=new s[3];
复制代码
的代码生成的汇编代码相当于一个循环。但是我看它的反汇编没有看懂,因为我觉得反汇编的实现应该比这个伪代码复杂。
书上说伪代码是像这样的:

  1. void* operator new(size_t len,void* pCtor, void* pDtor){
  2.     void*p=malloc(len);
  3.     for(int i=0;i<len/sizeof(s);++i){
  4.         s* ps=*(p+i);
  5.         new(ps) s();//构造函数,放置语法
  6.     }
  7. }
复制代码
我在VC10下面编release版的代码测试了一下。编译器为new s[..]生成的代码首先push了ctor和dtor,然后call一个函数。

  1. #include<stdio.h>
  2. struct s{
  3.         s(){printf("ctor\n");}
  4.         ~s(){printf("dtor\n");}
  5.         int i,j;
  6. };
  7. int main(void){
  8.         int *pi=new int;
  9.         int *pj=new int[3];

  10.         s* ps=new s;
  11.         s* pt=new s[4];
  12.         return 0;
  13. }
复制代码
其中,new数组的反汇编代码是:
        s* pt=new s[4];
0138107E  push        24h  
01381080  call        operator new[] (13810C5h)  
01381085  add         esp,4  
01381088  mov         dword ptr [ebp-10h],eax  
0138108B  mov         dword ptr [ebp-4],0  
01381092  test        eax,eax  
01381094  je          main+83h (13810B3h)  
01381096  push        offset s::~s (1381020h)  
0138109B  push        offset s::s (1381000h)  
013810A0  push        4  
013810A2  mov         dword ptr [eax],4  
013810A8  push        8  
013810AA  add         eax,4  
013810AD  push        eax  
013810AE  call        `eh vector constructor iterator' (13810E6h)  
        return 0;
013810B3  xor         eax,eax  

跟进去看call语句调用的地方。
反汇编窗口显示,call的这个函数没有源代码,只有反汇编语句:
--- No source file -------------------------------------------------------------
013810DF  int         3  
operator new:
013810E0  jmp         dword ptr [__imp_operator new (13820A0h)]  
`eh vector constructor iterator':
013810E6  push        10h  
013810E8  push        offset ___rtc_tzz+4 (13821D8h)  
013810ED  call        __SEH_prolog4 (1381550h)  
013810F2  xor         eax,eax  
013810F4  mov         dword ptr [ebp-20h],eax  
013810F7  mov         dword ptr [ebp-4],eax  
013810FA  mov         dword ptr [ebp-1Ch],eax  
013810FD  mov         eax,dword ptr [ebp-1Ch]  
01381100  cmp         eax,dword ptr [ebp+10h]  
01381103  jge         `eh vector constructor iterator'+32h (1381118h)  
01381105  mov         esi,dword ptr [ebp+8]  
01381108  mov         ecx,esi  
0138110A  call        dword ptr [ebp+14h]  
0138110D  add         esi,dword ptr [ebp+0Ch]  
01381110  mov         dword ptr [ebp+8],esi  
01381113  inc         dword ptr [ebp-1Ch]  
01381116  jmp         `eh vector constructor iterator'+17h (13810FDh)  
01381118  mov         dword ptr [ebp-20h],1  
0138111F  mov         dword ptr [ebp-4],0FFFFFFFEh  
01381126  call        $LN9 (1381133h)  
$LN12:
0138112B  call        __SEH_epilog4 (1381595h)  
01381130  ret         14h  

我的问题是,像书上那样只是一个for循环的话,应该代码没有这么长啊。
这一长串的反汇编语句除了一个循环以外,还做了什么?
看起来是做了一个异常处理,如果某次构造函数失败了,就调用dtor。
但是:
(1)为什么调用了两次跳转指令,跳到eh vector constructor iterator呢?
(2)mov指令太多了,不像是只做了一个循环的样子。还做了什么?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP