char *p = “\x9d\x01\x2a”;
if( *p == 0x9d && *(p+1) == 0x01 && *(p+2) == 0x2a)
{
...
}
可是括号里的代码却总是不执行,好奇怪。
然后我写了个小程序测试了一下:
#include "stdio.h"
#include <iostream>
using namespace std;
int main()
{
char *p = "\x9d\xb6\x2a\xa8";
if( */*(unsigned char*)*/p == 0x9d && *(p+1) == 0xb6 && *(p+2) == 0x2a)
cout << "yes" << endl;
else
cout << "no" << endl;
short int a = *(short int*)p;
if( a == 0xb69d )
cout << "yes" << endl;
else
cout << "no" << endl;
int b = *(int*)p;
if( b == 0xa82ab69d )
cout << "yes" << endl;
else
cout << "no" << endl;
return 0;
}
结果是no,no,yes
汇编代码如下:
00D814D5 8B 45 F8 mov eax,dword ptr [p]
00D814D8 0F BE 08 movsx ecx,byte ptr [eax]
00D814DB 81 F9 9D 00 00 00 cmp ecx,9Dh
...
short int a = *(short int*)p;
00CE1556 8B 45 F8 mov eax,dword ptr [p]
00CE1559 66 8B 08 mov cx,word ptr [eax]
00CE155C 66 89 4D EC mov word ptr [a],cx
15:
16: if( a == 0xb69d )
00CE1560 0F BF 45 EC movsx eax,word ptr [a]
00CE1564 3D 9D B6 00 00 cmp eax,0B69Dh
00CE1569 75 2D jne main+0E8h (0CE1598h)
...
int b = *(int*)p;
00CE15C3 8B 45 F8 mov eax,dword ptr [p]
00CE15C6 8B 08 mov ecx,dword ptr [eax]
00CE15C8 89 4D E0 mov dword ptr [b],ecx
22:
23: if( b == 0xa82ab69d )
00CE15CB 81 7D E0 9D B6 2A A8 cmp dword ptr [b],0A82AB69Dh
00CE15D2 75 2D jne main+151h (0CE1601h)
可以看出,编译器将该比特带符号扩展成了int,就变成了FFFFFF9D,再与9D比较,自然就不等了。
同理将short带符号扩展成int型的FFFFB69D。这应该就是所谓的“整形提升”吧。而int型的不管是正的还是负的,测试的结果都是相等。
当我把判断的那句改成:if( *(unsigned char*)p == 0x9d && *(unsigned char*)(p+1) == 0xb6 && *(p+2) == 0x2a),结果为yes, no ,yes。
汇编码如下:
00D814D5 8B 45 F8 mov eax,dword ptr [p]
00D814D8 0F BE 08 movzx ecx,byte ptr [eax]
00D814DB 81 F9 9D 00 00 00 cmp ecx,9Dh
结果自然相等了。
以上说明char, short等长度小于int长度的类型在比较的时候,会存在整形提升。符号的正负取决于数据是有符号的还是无符号的。