习惯性的用strlen来取得字符串的长度,却不想昨天也在这个上面犯了点粘错误!
原来,对于字符串中含有字节为“0”的话,获取的将是错误的,因为strlen的处理是:
碰到0字节时将直接返回,而不考虑后面是否有值,如下:
00407818 |. 8B41 FC |mov eax,dword ptr ds:[ecx-4]========取字符
0040781B |. 84C0 |test al,al ========判断是否为0了
0040781D |. 74 32 |je short test.00407851 ========是,就只好直接退出了!
今天起来,特意写了一个小例子,多看看了一下,呵呵:
#include
using namespace std;
int main()
{
char szTest[20];
memset(szTest,0,20);
szTest[1]='A';
szTest[3]='B';
szTest[6]='C';
szTest[7]='D';
//我们现在来查找最后一个出现的字母C的索引!
__asm{
inc eax
dec eax
}
int i=strlen(szTest)-1;
for(;i>=0;i--)
{
if(szTest[i]=='C')
break;
}
cout<<"The C index is :"< //得到的输出是:The C index is :-1
return 0;
}
反汇编后:
00401020 |. C645 E5 41 mov byte ptr ss:[ebp-1B],41 ; szTest[1]='A';
00401024 |. C645 E7 42 mov byte ptr ss:[ebp-19],42 ; szTest[3]='B';
00401028 |. C645 EA 43 mov byte ptr ss:[ebp-16],43 ; szTest[6]='7';
0040102C |. C645 EB 44 mov byte ptr ss:[ebp-15],44 ; szTest[7]='D';
00401030 |. 40 inc eax
00401031 |. 48 dec eax
00401032 |. 8D4D E4 lea ecx,dword ptr ss:[ebp-1C] ; int i=strlen(szTest)-1;
00401035 |. 51 push ecx
00401036 |. E8 95670000 call test.004077D0 ; 因为szTest的第一个是0
0040103B |. 83C4 04 add esp,4 ; 所以这里取长度就已经出错了,返回的是0
0040103E |. 83E8 01 sub eax,1 ; 减去1,就是0xFFFFFFFF了,也即-1
00401041 |. 8945 FC mov dword ptr ss:[ebp-4],eax
00401044 |. C745 FC 12000000 mov dword ptr ss:[ebp-4],12
0040104B |. EB 09 jmp short test.00401056
0040104D |> 8B55 FC /mov edx,dword ptr ss:[ebp-4]
00401050 |. 83EA 01 |sub edx,1
00401053 |. 8955 FC |mov dword ptr ss:[ebp-4],edx ; 为里比较就不能过了,直接退出了循环
00401056 |> 837D FC 00 cmp dword ptr ss:[ebp-4],0
0040105A |. 7C 11 |jl short test.0040106D
0040105C |. 8B45 FC |mov eax,dword ptr ss:[ebp-4]
0040105F |. 0FBE4C05 E4 |movsx ecx,byte ptr ss:[ebp+eax-1C>
00401064 |. 83F9 43 |cmp ecx,43
00401067 |. 75 02 |jnz short test.0040106B
00401069 |. EB 02 |jmp short test.0040106D
0040106B |>^ EB E0 \jmp short test.0040104D
0040106D |> 68 00114000 push test.00401100
写在这里,以作记念吧!