反汇编学习之整数类型

            C++提供的整数类型包括short、int和long,每种类型都分为有符号和无符号两种类型,在笔者另一篇文章中叙述过,在不同的编译器下实现不同,三种类型在内存中所占的大小也不统一。在VC和GCC下,short占2字节,int占4字节,long占4字节,long long占8字节。下面的讲解中都以用得较多的int类型为例。

       1.  无符号整数

        unsigned int在内存中占4字节,并且所有的32位都用来表示数值,可以表示的范围为0x00000000~0xFFFFFFFF,也就是0~4294967295。可以表示的正数范围为有符号数的两倍,当无符号数不足32位时,高位补0。

        计算机存储的单位是字节,这四个字节在内存中如何存放就有两种方法了,也就是常听到的大端和小端的概念了,即big-endian和little-endian(endian意思为字节存储次序)。小端模式即低位数据排在低端,高位数据排在高端,大端即相反。对于0x12345678来说,从内存地址0x40000000开始存,如果是小端模式,则从0x40000000~0x40000003四个地址分别为78、56、34、12,大端模式的话,为12、34、56、78。内存地址是从低到高的,大端就是大的(即高位)在最头面,小端即小的(即低位)在最头面。

int main(void)
{
    unsigned int i = 0x12345678;
    return 0;
}
查看i的内存空间有如下显示:


可以看到i从0x28ff1c单元开始存放,为小端模式。

        2. 有符号整数

       有符号整数用最高位表示符号,0为正数,1为负数。因为最高位不能表示数值,所以表示整数的范围为0x80000000~0x7FFFFFFF,即-2147483648~2147483647,正数的表示区间为0x00000000~0x7FFFFFFF,负数的表示区间为0x80000000~0xFFFFFFFF。看到这里,你可能会产生疑惑正数范围还好说,负数就有点看不懂了。下面先来复习一下原码、反码和补码的知识,上面的负数范围就很好理解了。

       因为计算机只会做加法,所以需要把减法转换为加法,至于为什么计算机只会做加法,没有查到权威的解释,意思就是所有的运算都转换为加法再计算。

       负数在内存中都是以补码形式存放的,补码的规则是对这个数值取反加1。对于任何4字节的数值x,都有x + x(反)= 0xFFFFFFFF,于是x + x(反) + 1 = 0,x = -(x(反) +1)。对于0xFFFFFFFF,取反后为0x00000000,加1再乘以-1后为-1。对于0x80000000,可以表达的意义可以是负数0,也可以是0x80000001减去1,由于0的正负值相等,没有必要再来负数0,所以规定为0x80000001(-2147483647)减去1,这样0x8000000也就成为4字节负数的最小值。这就是为什么有符号整数的取值范围中,负数总比整数多一个最小值的原因。

       补码也定义为用0减去这个数的绝对值,即x(绝对值) + x(补码) = 0, 对于-1,补码为0 - 1,即0xFFFFFFFF + 0x00000001 = 0,所以-1的补码为0xFFFFFFFF。

int main(void)
{
    int i = -1;
    return 0;
}


       3. 总结

       在对整数的内存进行分析时,只通过内存中的数值是不能够判断是有符号还是无符号数,需要查看指令或者已知函数如何操作此内存地址,根据操作方式或函数相关定义得出该地址的数据类型,如API调用MessageBox,它有4个参数,查看帮助得知,第四个参数为一个无符号整数,从而再进行数值的分析。

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值