PoEdu_反汇编003_数据类型

数据类型:

      C/C++语言中,数据类型有很多,常用的:int、long、short、char以及他们的unsigned型。我们熟知,int、long都是占用32位(4字节)。short占16位(2字节)。int和long的范围为0x00000000~0x7FFFFFFF、0x80000000~0xFFFFFFFF。对应的unsigned型范围为:0x00000000~0xFFFFFFFF。而short也类似,都是基础知识,这里不做介绍。

      在内存中,数字都是二进制,为了方便,通常都是按十六进制显示的,例如int中的100,实际上是0x64,然而,数据本身是4字节,其他的应该填充0,所以实际上是0x00000064。long也一样,short也类似,下面,我们回来验证。

汇编下的数据类型:

      分析程序如下:


      在内存窗口中,我们输入&n_i,查看n_i的内存处,可以看见如下:


      可以发现,里面全是CCCCCCCC,这是由于VS工具在没有使用的位置全部初始化成CCCCCCCC,方便我们调试,然后,F10,执行一步程序,可以发现,上图黄色区域的四个字节变成了(64 00 00 00),并不是(00 00 00 64),同样的,我们在将内存窗口定位到u_i变量的内存位置,执行程序到初始化u_i,可发现,还是一样的效果,实际上,Windows存储数据本来就是按照这样,低位对应内存低位,高位对应内存高位。实际上这被称为小尾方式存储。对应的也有大尾方式,只是存储方式的不同,但我们任然可以理解,实际上,存储的就是0x00000064。

      补码:计算机中,负数存储的是补码,不嘛的计算等是计算机基础知识,这里不做介绍,但是,这对反汇编很重要。

      然而,这里存在一点比较让人疑惑,在汇编中,有符号和无符号的int都是占用32位,例如-2,即0xFFFFFFFE,按照有符号解析,就是-2,按照无符号解析,就是‭4294967294‬,结果完全不一样。我们在看反汇编的时候,同样是32位,如果没区分好有符号无符号,结果就可能大不一样,因此,在分析反汇编程序的时候,需要通过其他的方式区分有无符号

      在汇编中,有时候,我们还需要保存浮点数,C/C++中,用float和double保存浮点数,区别在于占用字节不一样,double占用8字节float占用四字节,double精度更高。两者都是使用的IEEE编码

IEEE编码:

      IEEE编码以科学计数法将浮点数的二进制分为符号位,指数,尾数三部分,以float为例,首位为符号位,之后8位为指数为,后面23位均为尾数部分

      例如使用float保存12.25ff:12的二进制为1100,0.25的二进制为.01(8 4 2 1 . 1/2 1/4 1/8)因此,12.25保存为二进制为1100.01即1.10001,指数为3是一个正数,符号位为0指数为3,需要加127,=130,放在指数位为10000010在IEEE编码中,首位恒定为1(1.10001中第一个1),因此可以不记录,可以直接将10001保存在尾数部分,尾数不足时,全部补0

      double的数据存储也是大同小异,对于浮点数,特别注意的是其转换过程,对于CPU中,也有专门的浮点数寄存器。

程序分析:

对指针和数组的分析:


    可以看出,第一个就是指针的赋值,说到指针大家可能更难理解,实际上,这一步就是将0x011ECD1C这个数赋值到一个指针中(char*),这个指针虽然是char*,但是char*是指针,也是占4字节,只有char是占1字节

    下一条C++代码:char arr_str[] = "I Love Mark";被翻译成了很长的代码:如下:


      看起来,被翻译成了很多行,然而,实际上做的事情很简单,就是将“I Love Mark”按照4字节的单位搬到arr_str中,我们可以发现,实际上,代码是有规律的,分三次,每次将四字节搬到数据寄存器eax,然后,将eax搬到对应的内存地址,这里内存地址也是每次移动四个。搬到的地方为栈区,之前我们就已经知道了ebp为栈顶。

对指针和引用的分析:


      上面代码,我们可以看出,指针和引用的汇编代码完全一样,都是使用lea指令取出地址,再将地址赋给变量。因为,引用属于编译时期检查,对于最终的运行没有任何影响,他只作用于编译器,在编译的时候的一些处理。在反汇编时,我们看不出是使用的引用还是指针,但是,他们最终效果都一样,这并不影响我们的反汇编过程。

      引用并不会影响程序的执行速度,而且还比指针多了编译器的一些检测,所以,在C++编程的时候,使用引用更好。

对宏定义和const的分析


      我们可以看到,宏定义本身不会产生汇编代码,而在使用的时候,直接就替换了,直接使用的64h,而const却和普通的赋值是一样的,在汇编下,加const和不加const,本质一样这也从本质上说明了,const只是作用于编译器,是编译期间使用的。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值