- UID
- 2
- 精华
- 积分
- 7736
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
重识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
转换后T2 | 1字节整形(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方式清零,通常会优化为各个成员清零 |
|