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的内存结构就可以了,一般是先定义的变量在低地址,后定义的变量在高地址。