UID 2
精华 76
积分 7349
威望 291 点
宅币 5599 个
贡献 253 次
宅之契约 0 份
最后登录 2024-5-1
在线时间 949 小时
QQ
用户组: 真·技术宅
UID 2
精华 76
威望 291 点
宅币 5599 个
贡献 253 次
宅之契约 0 份
在线时间 949 小时
注册时间 2014-1-25
重识C++ 基本类型及其转换
C++基本类型分为整数类型、浮点类型和其他类型
整数类型:char,bool,short,int,__intn(__int8,__int16,__int32,__int64),long,long long
浮点数类型:float,double,long doubleq
其他类型:__wchar_t,bool,void,
nullptr:用于定义空指针
__m64,__m128,__m128d,__m128i:MMX和3Dnow!中使用类型,定义在xmmintrin.h。
__ptr32,__ptr64:32位系统和64位系统所用本地指针
带有“__”的类型为非标准类型
类型 占字节 别名 表示范围 int 4 signed –2,147,483,648 to 2,147,483,647 unsigned int 4 unsigned 0 to 4,294,967,295 __int8 1 char –128 to 127 unsigned __int8 1 unsigned char 0 to 255 __int16 2 short, short int, signed short int –32,768 to 32,767 unsigned __int16 2 unsigned short, unsigned short int 0 to 65,535 __int32 4 signed, signed int, int –2,147,483,648 to 2,147,483,647 unsigned __int32 4 unsigned, unsigned int 0 to 4,294,967,295 __int64 8 long long, signed long long –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 unsigned __int64 8 unsigned long long 0 to 18,446,744,073,709,551,615 bool 1 none false or true char 1 none –128 to 127 signed char 1 none –128 to 127 unsigned char 1 none 0 to 255 short 2 short int, signed short int –32,768 to 32,767 unsigned short 2 unsigned short int 0 to 65,535 long 4 long int, signed long int –2,147,483,648 to 2,147,483,647 unsigned long 4 unsigned long int 0 to 4,294,967,295 long long 8 none (but equivalent to __int64) –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 unsigned long long 8 none (but equivalent to unsigned __int64) 0 to 18,446,744,073,709,551,615 enum varies none float 4 none 3.4E +/- 38 (7 digits) double 8 none 1.7E +/- 308 (15 digits) long double same as double none Same as double wchar_t 2 __wchar_t 0 to 65,535
上表针对MSVC中的所有整数类型之间强制转换情况进行了统计,当较小长度类型转换为较大长度类型时通常使用扩展mov指令,而较大长度类型转换为较小长度类型时仅需将地位mov操作。使用的样例为T1 t1;T2 t2 =(T2)t1;。表中的s和u分别代表unsigned和signed,即无符号和有符号情况。仅以MSVC 32位 debug版本为例。
测试源码:#include <iostream>
using namespace std;
template<typename T1,typename T2>
void explicit_cast()
{
T1 s1,d2;
T2 d1,s2;
cin>>s1>>s2>>d1>>d2;
cout<<"T1:"<<typeid(T1).name()<<" T2:"<<typeid(T2).name()<<endl;
d1=(T2)s1;
d2=(T1)s2;
cout<<d1<<d2<<endl;
}
#define all_cast1(x,y) \
{\
explicit_cast<x,y>();\
explicit_cast<unsigned x,y>();\
explicit_cast<x,unsigned y>();\
explicit_cast<unsigned x,unsigned y>();\
}
#define all_cast2(x,y) \
{\
explicit_cast<x,y>();\
explicit_cast<unsigned x,y>();\
}
void main()
{
all_cast1(char,char);
all_cast1(char,short);
all_cast1(char,int);
all_cast1(char,long long);
all_cast2(char,float);
all_cast2(char,double);
all_cast1(short,short);
all_cast1(short,int);
all_cast1(short,long long);
all_cast2(short,float);
all_cast2(short,double);
all_cast1(int,int);
all_cast1(int,long long);
all_cast2(int,float);
all_cast2(int,double);
all_cast1(long long,long long);
all_cast2(long long,float);
all_cast2(long long,double);
explicit_cast<float,float>();
explicit_cast<float,double>();
explicit_cast<double,double>();
} 复制代码 转换前T1
转换后T21字节整形(char,bool,__int8) 2字节整形(short,__int16) 4字节整形(int,__int32,long) 8字节整形(__int64,long long) 4字节浮点(float) 8字节浮点(double,long double) 1字节整形(char,bool,__int8) s->s mov
u->s mov
s->u mov
u->u mov s->s mov
u->s mov
s->u mov
u->u mov s->s mov
u->s mov
s->u mov
u->u mov s->s mov
u->s mov
s->u mov
u->u mov s->s cvttss2si
mov
s->u cvtts2si
mov s->s cvttsd2si
mov
s->u cvttsd2si
mov 2字节整形(short,__int16) s->s movsx
u->s movzx
s->u movsx
u->u movzx s->s mov
u->s mov
s->u mov
u->u mov s->s mov
u->s mov
s->u mov
u->u mov s->s mov
u->s mov
s->u mov
u->u mov s->s cvttss2si
mov
s->u cvtts2si
mov s->s cvttsd2si
mov
s->u cvttsd2si
mov 4字节整形(int,__int32,long) s->s movsx cdq
u->s movzx cdq
s->u movsx cdq
u->u movzx cdq
s->s movsx
u->s movzx
s->u movsx
u->u movzx s->s mov
u->s mov
s->u mov
u->u mov s->s mov
u->s mov
s->u mov
u->u mov s->s cvttss2si
mov
s->u 见②
s->s cvttsd2si
mov
s->u 见④ 8字节整形(__int64,long long) s->s movsx cdq
u->s movzx cdq
s->u movsx cdq
u->u movzx cdq s->s movsx cdq
u->s movzx cdq
s->u movsx cdq
u->u movzx cdq s->s mov cdq
u->s mov xor
s->u mov cdq
u->u mov xor s->s mov
u->s mov
s->u mov
u->u mov s->s fld
__ftol2
mov
s->u movss s->s fld
__ftol2
mov
s->u 见⑥ 4字节浮点(float) s->s movsx
cvtsi2ss
movss
u->s movzx
cvtsi2ss
movss s->s movsx
cvtsi2ss
movss
u->s movzx
cvtsi2ss
movss s->s cvtsi2ss
movss
u->s 见① s->s fild fstp
movss
u->s xorpd
movlpd movss
cvtsd2ss
movss 8字节浮点(double,long double) s->s movsx
cvtsi2sd
movsd
u->s movzx
cvtsi2sd
movsd s->s movsx
cvtsi2sd
movsd
u->s movzx
cvtsi2sd
movsd s->s cvtsi2sd
movsd
u->s 见③ s->s fild fstp
u->s 见⑤ cvtss2sd
movsd movsd
由于是debug版本,所以指令较多
①Unsigned int s1;float d1=(float)s1;
00082AC1 mov eax,dword ptr [s1]
00082AC4 mov dword ptr [ebp-0F4h],eax
00082ACA cvtsi2sd xmm0,dword ptr [ebp-0F4h]
00082AD2 mov ecx,dword ptr [ebp-0F4h]
00082AD8 shr ecx,1Fh
00082ADB addsd xmm0,mmword ptr [ecx*8+8FD70h]
00082AE4 movsd mmword ptr [ebp-0FCh],xmm0
00082AEC cvtsd2ss xmm0,mmword ptr [ebp-0FCh]
00082AF4 movss dword ptr [d1],xmm0
②float s2;unsigned int d2=(unsignd int)s2;
00082AF9 fld dword ptr [s2]
00082AFC fnstcw word ptr [ebp-0F2h]
00082B02 movzx eax,word ptr [ebp-0F2h]
00082B09 or eax,0C00h
00082B0E mov dword ptr [ebp-0F8h],eax
00082B14 fldcw word ptr [ebp-0F8h]
00082B1A fistp qword ptr [ebp-100h]
00082B20 fldcw word ptr [ebp-0F2h]
00082B26 mov eax,dword ptr [ebp-100h]
00082B2C mov dword ptr [d2],eax
③Unsigned int s1;doublet d1=(double)s1;
00D52CD5 mov eax,dword ptr [s1]
00D52CD8 mov dword ptr [ebp-0FCh],eax
00D52CDE cvtsi2sd xmm0,dword ptr [ebp-0FCh]
00D52CE6 mov ecx,dword ptr [ebp-0FCh]
00D52CEC shr ecx,1Fh
00D52CEF addsd xmm0,mmword ptr [ecx*8+0D5FD70h]
00D52CF8 movsd mmword ptr [d1],xmm0
④double s2;unsigned int d2=(unsigned int)s2;
00D52CFD fld qword ptr [s2]
00D52D00 fnstcw word ptr [ebp-0FAh]
00D52D06 movzx eax,word ptr [ebp-0FAh]
00D52D0D or eax,0C00h
00D52D12 mov dword ptr [ebp-100h],eax
00D52D18 fldcw word ptr [ebp-100h]
00D52D1E fistp qword ptr [ebp-108h]
00D52D24 fldcw word ptr [ebp-0FAh]
00D52D2A mov eax,dword ptr [ebp-108h]
00D52D30 mov dword ptr [d2],eax
⑤Unsigned long long s1;doublet d1=(double)s1;
00D53F39 mov eax,dword ptr [s1]
00D53F3C mov ecx,dword ptr [ebp-8]
00D53F3F mov dword ptr [ebp-108h],eax
00D53F45 mov dword ptr [ebp-104h],ecx
00D53F4B mov edx,dword ptr [ebp-104h]
00D53F51 mov dword ptr [ebp-10Ch],edx
00D53F57 and dword ptr [ebp-104h],7FFFFFFFh
00D53F61 fild qword ptr [ebp-108h]
00D53F67 and dword ptr [ebp-10Ch],80000000h
00D53F71 mov dword ptr [ebp-110h],0
00D53F7B fild qword ptr [ebp-110h]
00D53F81 fchs
00D53F83 faddp st(1),st
00D53F85 fstp qword ptr [d1]
⑥double s2;unsigned long long d2=(unsigned long long)s2;
00D53F88 xorpd xmm0,xmm0
00D53F8C movlpd qword ptr [ebp-108h],xmm0
00D53F94 fld qword ptr [s2]
00D53F97 fstp qword ptr [ebp-110h]
00D53F9D fld qword ptr ds:[0D5FBC0h]
00D53FA3 fld qword ptr [ebp-110h]
00D53FA9 fcomip st,st(1)
00D53FAB fstp st(0)
00D53FAD jb explicit_cast<unsigned __int64,double>+174h (0D53FE4h)
00D53FAF fld qword ptr [ebp-110h]
00D53FB5 fsub qword ptr ds:[0D5FBC0h]
00D53FBB fstp qword ptr [ebp-110h]
00D53FC1 fld qword ptr [ebp-110h]
00D53FC7 fld qword ptr ds:[0D5FBC0h]
00D53FCD fcomip st,st(1)
00D53FCF fstp st(0)
00D53FD1 jbe explicit_cast<unsigned __int64,double>+174h (0D53FE4h)
00D53FD3 add dword ptr [ebp-108h],0
00D53FDA adc dword ptr [ebp-104h],80000000h
00D53FE4 fld qword ptr [ebp-110h]
00D53FEA call __ftol2 (0D5147Eh)
00D53FEF add eax,dword ptr [ebp-108h]
00D53FF5 adc edx,dword ptr [ebp-104h]
00D53FFB mov dword ptr [ebp-118h],eax
00D54001 mov dword ptr [ebp-114h],edx
00D54007 mov eax,dword ptr [ebp-118h]
00D5400D mov dword ptr [d2],eax
00D54010 mov ecx,dword ptr [ebp-114h]
00D54016 mov dword ptr [ebp-18h],ecx
代码先放在这里,后面有时间会分析,同时也会出现在我的书里
对于多继承类指针类型转换的情况比较复杂,在我的逆向书中将会有讨论。
变量赋值方式 T t=0; 编译环境vs2012 32位
测试代码:#include <iostream>
using namespace std;
template<typename T>
void assignment()
{
cout<<"T:"<<typeid(T).name()<<endl;
//初始化
T s1=0,s2=1;
//赋值
s1=1;
s2=0;
}
#define all_assign(x) \
{\
assignment<x>();\
assignment<unsigned x>();\
}
void main()
{
all_assign(char);
assignment<bool>();
all_assign(__int8);
all_assign(short);
all_assign(__int16);
all_assign(int);
all_assign(__int32);
all_assign(long);
all_assign(long long);
all_assign(__int64);
assignment<float>();
assignment<double>();
assignment<long double>();
} 复制代码 1/2/4字节整形
(char,bool,__int8,
short,__int16,int,
__int32,long) 8字节整形
(__int64,long long) 4字节浮点
(float) 8字节浮点
(double,long double) 赋值为零 mov xorpd movlpd movss movsd 赋值为非零 mov mov movss movsd
对于结构体memset方式清零,通常会优化为各个成员清零