string类函数分析

1.empty函数分析

string d;

004017AD   lea         eax,[ebp-20h] //这个变量应该是给string类一个标志赋值。没多大用
004017B0   push        eax      //参数压栈,
004017B1   lea         ecx,[ebp-1Ch] //this指针压栈
004017B4   call        @ILT+675(std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_str//调用构造函数
004017B9   mov         dword ptr [ebp-4],0 //这个变量保存申请堆栈的次数


d.empty();

004012C0   lea         ecx,[ebp-1Ch] //this指针

004012C3   call        @ILT+10(std::basic_string<char,std::char_traits<char>,std::allocator<char> >::empty) (00//调用empty函数

004013D0   push        ebp
004013D1   mov         ebp,esp
004013D3   sub         esp,44h
004013D6   push        ebx
004013D7   push        esi
004013D8   push        edi
004013D9   push        ecx
004013DA   lea         edi,[ebp-44h]
004013DD   mov         ecx,11h
004013E2   mov         eax,0CCCCCCCCh
004013E7   rep stos    dword ptr [edi]              //以上代码分配堆栈空间
004013E9   pop         ecx       //this指针
004013EA   mov         dword ptr [ebp-4],ecx     
004013ED   mov         eax,dword ptr [ebp-4]    //由于是debug没有进行优化,这里赋值有点赘余
004013F0   xor         ecx,ecx
004013F2   cmp         dword ptr [eax+8],0    //this存储的内存信息   ,前面四个字节好像是个标志没用,接着四个字节是存储的字符串所在的地址,接着四个字节是长度(这里我们可以看到是0),后面四个字节貌似是引用的次数。
004013F6   sete        cl   //cl等于ZF,相减之后为0,所以ZF为1

004013F9   mov         al,cl //函数返回值一般用eax保存,所以这里返回是1,这个字符串是空的。
004013FB   pop         edi
004013FC   pop         esi
004013FD   pop         ebx
004013FE   mov         esp,ebp
00401400   pop         ebp
00401401   ret


2.size分析 其实这个函数跟上面的类似。也是取this的第8个字节开始   


3.s[n]分析

char c = d[0];
00401355   push        0
00401357   lea         ecx,[ebp-1Ch]
0040135A   call        @ILT+55(std::basic_string<char,std::char_traits<char>,std::allocator<char> >::operator[]//调用重载操作符函数
0040135F   mov         cl,byte ptr [eax]  //获取字符
00401361   mov         byte ptr [ebp-20h],cl //赋值给局部变量


s【n】反汇编

00401480   push        ebp
00401481   mov         ebp,esp
00401483   sub         esp,44h
00401486   push        ebx
00401487   push        esi
00401488   push        edi
00401489   push        ecx
0040148A   lea         edi,[ebp-44h]
0040148D   mov         ecx,11h
00401492   mov         eax,0CCCCCCCCh
00401497   rep stos    dword ptr [edi]   //分配栈
00401499   pop         ecx
0040149A   mov         dword ptr [ebp-4],ecx
0040149D   mov         eax,dword ptr [ebp-4]
004014A0   mov         ecx,dword ptr [eax+8] //获取string字符串,字符个数
004014A3   cmp         ecx,dword ptr [ebp+8] //string字符串个数与n做比较,ebp+8是传递过来的第几个字符
004014A6   jb          std::basic_string<char,std::char_traits<char>,std::allocator<char> >::operator[]+31h (00//小于则跳转到004014B1
004014A8   mov         edx,dword ptr [ebp-4]    //如果所取字符串大于传递的参数则执行,取的this
004014AB   cmp         dword ptr [edx+4],0     //比较this存储的字符串指针是不是指向null
004014AF   jne         std::basic_string<char,std::char_traits<char>,std::allocator<char> >::operator[]+38h (00//不是则跳转到004014B8 
004014B1   call        @ILT+15(std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Nullstr)//错误处理
004014B6   jmp         std::basic_string<char,std::char_traits<char>,std::allocator<char> >::operator[]+49h (00//跳转004014C0   
004014B8   mov         ecx,dword ptr [ebp-4]   //获取this指针
004014BB   call        @ILT+45(std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Freeze) (//这个函数主要就检查合法性
004014C0   mov         eax,dword ptr [ebp-4]
004014C3   mov         eax,dword ptr [eax+4]//获取字符串首地址
004014C6   add         eax,dword ptr [ebp+8]//加上所取的位置,返回所取字符的首地址
004014C9   pop         edi
004014CA   pop         esi
004014CB   pop         ebx
004014CC   add         esp,44h
004014CF   cmp         ebp,esp
004014D1   call        __chkesp (00408740)
004014D6   mov         esp,ebp
004014D8   pop         ebp
004014D9   ret         4


总结string的这些函数还是挺简单的,只要弄清楚string的内存结构就可以了,一般是先定义的变量在低地址,后定义的变量在高地址。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值