元始天尊 发表于 2014-11-8 12:30:54

重识C++基本类型及其转换

重识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位系统所用本地指针

带有“__”的类型为非标准类型

类型占字节别名表示范围
int4signed–2,147,483,648 to 2,147,483,647
unsigned int4unsigned0 to 4,294,967,295
__int81char–128 to 127
unsigned __int81unsigned char0 to 255
__int162short, short int, signed short int–32,768 to 32,767
unsigned __int162unsigned short, unsigned short int0 to 65,535
__int324signed, signed int, int–2,147,483,648 to 2,147,483,647
unsigned __int324unsigned, unsigned int0 to 4,294,967,295
__int648long long, signed long long–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
unsigned __int648unsigned long long0 to 18,446,744,073,709,551,615
bool1nonefalse or true
char1none–128 to 127
signed char1none–128 to 127
unsigned char1none0 to 255
short2short int, signed short int–32,768 to 32,767
unsigned short2unsigned short int0 to 65,535
long4long int, signed long int–2,147,483,648 to 2,147,483,647
unsigned long4unsigned long int0 to 4,294,967,295
long long8none (but equivalent to __int64)–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
unsigned long long8none (but equivalent to unsigned __int64)0 to 18,446,744,073,709,551,615
enumvariesnone
float4none3.4E +/- 38 (7 digits)
double8none1.7E +/- 308 (15 digits)
long doublesame as doublenoneSame as double
wchar_t2__wchar_t0 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 movs->s mov
u->s mov
s->u mov
u->u movs->s mov
u->s mov
s->u mov
u->u movs->s mov
u->s mov
s->u mov
u->u movs->s cvttss2si
    mov
s->u cvtts2si
    movs->s cvttsd2si
    mov
s->u cvttsd2si
    mov
2字节整形(short,__int16)s->s movsx
u->s movzx
s->u movsx
u->u movzxs->s mov
u->s mov
s->u mov
u->u movs->s mov
u->s mov
s->u mov
u->u movs->s mov
u->s mov
s->u mov
u->u movs->s cvttss2si
    mov
s->u cvtts2si
    movs->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 movzxs->s mov
u->s mov
s->u mov
u->u movs->s mov
u->s mov
s->u mov
u->u movs->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 cdqs->s movsx cdq
u->s movzx cdq
s->u movsx cdq
u->u movzx cdqs->s mov cdq
u->s mov xor
s->u mov cdq
u->u mov xors->s mov
u->s mov
s->u mov
u->u movs->s fld
    __ftol2
    mov
s->u movsss->s fld
    __ftol2
    mov
s->u 见⑥
4字节浮点(float)s->s movsx
    cvtsi2ss
    movss
u->s movzx
    cvtsi2ss
    movsss->s movsx
    cvtsi2ss
    movss
u->s movzx
    cvtsi2ss
    movsss->s cvtsi2ss
    movss
u->s 见①s->s fild fstp
    movss
u->s xorpd
    movlpdmovss
cvtsd2ss
movss
8字节浮点(double,long double)s->s movsx
    cvtsi2sd
    movsd
u->s movzx
    cvtsi2sd
    movsds->s movsx
    cvtsi2sd
    movsd
u->s movzx
    cvtsi2sd
    movsds->s cvtsi2sd
    movsd
u->s 见③s->s fild fstp
u->s 见⑤cvtss2sd
movsdmovsd
由于是debug版本,所以指令较多
①Unsigned int s1;float d1=(float)s1;
00082AC1mov         eax,dword ptr
00082AC4mov         dword ptr ,eax
00082ACAcvtsi2sd    xmm0,dword ptr
00082AD2mov         ecx,dword ptr
00082AD8shr         ecx,1Fh
00082ADBaddsd       xmm0,mmword ptr
00082AE4movsd       mmword ptr ,xmm0
00082AECcvtsd2ss    xmm0,mmword ptr
00082AF4movss       dword ptr ,xmm0

②float s2;unsigned int d2=(unsignd int)s2;
00082AF9fld         dword ptr
00082AFCfnstcw      word ptr
00082B02movzx       eax,word ptr
00082B09or          eax,0C00h
00082B0Emov         dword ptr ,eax
00082B14fldcw       word ptr
00082B1Afistp       qword ptr
00082B20fldcw       word ptr
00082B26mov         eax,dword ptr
00082B2Cmov         dword ptr ,eax

③Unsigned int s1;doublet d1=(double)s1;
00D52CD5mov         eax,dword ptr
00D52CD8mov         dword ptr ,eax
00D52CDEcvtsi2sd    xmm0,dword ptr
00D52CE6mov         ecx,dword ptr
00D52CECshr         ecx,1Fh
00D52CEFaddsd       xmm0,mmword ptr
00D52CF8movsd       mmword ptr ,xmm0

④double s2;unsigned int d2=(unsigned int)s2;
00D52CFDfld         qword ptr
00D52D00fnstcw      word ptr
00D52D06movzx       eax,word ptr
00D52D0Dor          eax,0C00h
00D52D12mov         dword ptr ,eax
00D52D18fldcw       word ptr
00D52D1Efistp       qword ptr
00D52D24fldcw       word ptr
00D52D2Amov         eax,dword ptr
00D52D30mov         dword ptr ,eax

⑤Unsigned long long s1;doublet d1=(double)s1;
00D53F39mov         eax,dword ptr
00D53F3Cmov         ecx,dword ptr
00D53F3Fmov         dword ptr ,eax
00D53F45mov         dword ptr ,ecx
00D53F4Bmov         edx,dword ptr
00D53F51mov         dword ptr ,edx
00D53F57and         dword ptr ,7FFFFFFFh
00D53F61fild      qword ptr
00D53F67and         dword ptr ,80000000h
00D53F71mov         dword ptr ,0
00D53F7Bfild      qword ptr
00D53F81fchs
00D53F83faddp       st(1),st
00D53F85fstp      qword ptr

⑥double s2;unsigned long long d2=(unsigned long long)s2;
00D53F88xorpd       xmm0,xmm0
00D53F8Cmovlpd      qword ptr ,xmm0
00D53F94fld         qword ptr
00D53F97fstp      qword ptr
00D53F9Dfld         qword ptr ds:
00D53FA3fld         qword ptr
00D53FA9fcomip      st,st(1)
00D53FABfstp      st(0)
00D53FADjb          explicit_cast<unsigned __int64,double>+174h (0D53FE4h)
00D53FAFfld         qword ptr
00D53FB5fsub      qword ptr ds:
00D53FBBfstp      qword ptr
00D53FC1fld         qword ptr
00D53FC7fld         qword ptr ds:
00D53FCDfcomip      st,st(1)
00D53FCFfstp      st(0)
00D53FD1jbe         explicit_cast<unsigned __int64,double>+174h (0D53FE4h)
00D53FD3add         dword ptr ,0
00D53FDAadc         dword ptr ,80000000h
00D53FE4fld         qword ptr
00D53FEAcall      __ftol2 (0D5147Eh)
00D53FEFadd         eax,dword ptr
00D53FF5adc         edx,dword ptr
00D53FFBmov         dword ptr ,eax
00D54001mov         dword ptr ,edx
00D54007mov         eax,dword ptr
00D5400Dmov         dword ptr ,eax
00D54010mov         ecx,dword ptr
00D54016mov         dword ptr ,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)
赋值为零movxorpd movlpdmovssmovsd
赋值为非零movmovmovssmovsd
对于结构体memset方式清零,通常会优化为各个成员清零

ydc1992 发表于 2014-11-8 19:14:28

截图一手好图,, 学了几天C++对这些不怎么懂

cyycoish 发表于 2014-11-11 23:24:04

好帖!好人!赞一个!
业界良心!

0xAA55 发表于 2014-11-19 21:53:26

楼主!楼主,请把原始WORD文件给我,我帮你排版

0xAA55 发表于 2014-11-23 22:29:43

其实可以在不支持float的平台上,通过定义class float来自制一个float
页: [1]
查看完整版本: 重识C++基本类型及其转换