【反汇编3】基本数据类型的表现形式

发布时间 2023-12-20 11:46:16作者: eques

参考书籍,《C++反汇编与逆向分析技术揭秘》。

 

这次主要研究各种数据在计算机里怎么存的,又要涉及补码、科学计数法等基础内容。这些课程计算机专业的都会学,但作为程序员未必有直观的体验,比如java或python程序员,他们不用自己管理内存,也就根本不会接触到这类内容,例如int i = -1; 对于他们也就意味着i这个变量为-1,他们不会去了解,在内存里i这个变量其实是FF FF FF FF。

 

如果要学反汇编,或作底层C的,这些知识就是很常用且很基础的了。

我作为一个java程序员来通过反汇编学习下,底层大神就请无视好了。

 

第一段  C代码如下:

# include <stdio.h>
void main() 
{
    int i = -1;
    int i1 = 1;
    int *p = &i;
    int *p1 = &i1;
}

一个无符号的i,一个有符号的i1。使用指针目的是获取到变量地址。

反汇编:

# include <stdio.h>
void main() 
{
009917B0  push        ebp  
009917B1  mov         ebp,esp  
009917B3  sub         esp,0F0h  
009917B9  push        ebx  
009917BA  push        esi  
009917BB  push        edi  
009917BC  lea         edi,[ebp-0F0h]  
009917C2  mov         ecx,3Ch  
009917C7  mov         eax,0CCCCCCCCh  
009917CC  rep stos    dword ptr es:[edi]  
    int i = -1;
009917CE  mov         dword ptr [i],0FFFFFFFFh  
    int i1 = 1;
009917D5  mov         dword ptr [i1],1  
    int *p = &i;
009917DC  lea         eax,[i]  
009917DF  mov         dword ptr [p],eax  
    int *p1 = &i1;
009917E2  lea         eax,[i1]  
009917E5  mov         dword ptr [p1],eax  
}
009917E8  xor         eax,eax  
009917EA  push        edx  
009917EB  mov         ecx,ebp  
009917ED  push        eax  
009917EE  lea         edx,ds:[991804h]  
009917F4  call        @_RTC_CheckStackVars@8 (09911D1h)  
009917F9  pop         eax  
009917FA  pop         edx  
}

单步调试,到指针那里,观察寄存器eax的值(指针的值临时存储在eax)。那就是变量的内存地址。然后查找该地址。可以看到i在内存中为ffffffff。-1的补码(1的反码+1)。

继续单步下去:

可以看到1在内存里存为01000000,这是“小尾”存储的方式,也就是说以字节为单位,低数据存在内存低端,高数据存在内存高端。如果是“大尾"方式,则应为00000001。

 

float 单精度浮点数     第一位符号位,8位指数,23位尾数。

double 双精度浮点数     第一位符号位,11位指数,52位尾数。

 由截图可知,1.01在内存中存为29 5c 8f c2 f5 f0 3f

因为”小尾“实际为 3f f0  f5 c2 8f 5c 29

即为0011 1111 1111 0000 0010 1000 1111 0101 1100 0010 1000 1111 0101 1100 0010 1001  
符号0
指数011 1111 1111