数据类型有哪些(数据处理的三种方法)

基础类型

子曾经曰过:程序员要对自己所写程序的每个字节都了如指掌。
Talk is cheap,show me the binary code. 
                                     by 高尔基

对于数据类型的分析,采用二进制文件和运行时的内存2个方面着手。

int / unsigned int

int

int n = 10;    // 全局整型变量n,编译链接后将放到.data段,
               // 而且只有这一个变量,那它就是放到.data的起始位置

int main()  // C语言的入口函数
{
        int n1 = n;
} 

二进制文件

执行命令:

arm-none-eabi-objdump -h main.elf

得到elf文件各段的信息, 重点看.data段


main.elf:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000000bc  00000000  00000000  00010000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000004  a0000000  000000bc  00020000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .comment      00000031  00000000  00000000  00020004  2**0
                  CONTENTS, READONLY
  3 .ARM.attributes 0000002e  00000000  00000000  00020035  2**0
                  CONTENTS, READONLY

  • 其中Size是段的大小,.data就是4,因为int型变量n就是4个字节大小。
  • VMA是运行地址0xa0000000。
  • LMA是load memory address及加载地址,为0xbc。
  • File off为文件中的偏移,为0x20000。
  • Algn对为对齐边界位置2**2即2的2次方=4,即4字节对齐。
  • 下面的是段的相关属性,暂不表。

注意.data的地方:File off为0x00020000,表示.data段的内容放在main.elf文件的0x00020000开始的位置。

所以我们执行命令:

 hexdump -C -s 0x20000 main.elf

得到如图高亮的位置 0a,就是10进制的10。

内存

需要用到qemu命令x和xp命令

x /
fmt addr
    Virtual memory dump starting at addr.
xp /
fmt addr
    Physical memory dump starting at addr.
    fmt is a format which tells the command how to format the data. Its syntax is: /{count}{format}{size}

    count 
        is the number of items to be dumped.
    format
        can be x (hex), d (signed decimal), u (unsigned decimal), o (octal), c (char) or i (asm instruction).
    size
        can be b (8 bits), h (16 bits), w (32 bits) or g (64 bits). On x86, h
 or w
 can be specified with the i format to respectively select 16 or 32 bit code instruction size.

因我们还没有启用MMU,物理地址和虚拟地址相同,我们用x或xp均可。

查看代码段的加载地址 0xbc 处的一个4字节的数据,用10进制的格式显示。执行:

x /1dw 0xbc

得到结果:10,如图:

查看代码段的运行时地址 0xa0000000 处的一个4字节的数据,用10进制的格式显示。执行:

x /1dw 0xa0000000

得到结果:10,如图:

再试一个负数-2:

int n = -2;    // 全局整型变量n,编译链接后将放到.data段,
               // 而且只有这一个变量,那它就是放到.data的起始位置

int main()  // C语言的入口函数
{
        int n1 = n;
} 

我们看到在内存中的16进制表示,这个是-2的补码表示。

综上:将int型变量在的分析完成。

unsigned int

对于正整数赋值给unsigned int,和int类似。重点研究一下将负整数赋值给unsigned int有什么特别的。

  • 对于无符号整形-2
unsigned int n = -2;    // 全局无符号整型变量n

int main()  // C语言的入口函数
{
        int n1 = n;
} 

查看代码段的运行时地址 0xa0000000 处的一个4字节的数据,用16进制的格式显示。执行:

x /1dw 0xa0000000

如图:

说明:将整形的负数赋值给无符号整形变量,是将负数的补码赋给变量。

下面类型的分析就只dump内存的内容来分析,因为内存中的数据就是从二进制文件加载来的。有兴趣的读者可自行验证,方法与int型类似。

(unsigned )long、short、char

与int、unsigned int类似,读者可自行实验。

float

上代码:

float f = -2.5f;   

int main()  // C语言的入口函数
{
        
} 

得到:

如图这个0xc0200000怎么来的呢?

这要从float的IEEE754标准来分析。参考:IEEE754 浮点数的表示方法_Dablelv的博客专栏-CSDN博客_浮点数表示方法

配合IEEE754标准,在网址:https://float.exposed/ 上可以直接查看输入的float数值的各种表示方式,比如本例中的-2.5,高亮的地方就是16进制的表示法:

float收工。

double

double d = -2.5;   

int main()  // C语言的入口函数
{
        
} 

因为double占8个字节,我们要1个16进制的g,得到:

同float,在网址:https://float.exposed/ 输入double型的-2.5。得到:

复合类型

指针

上代码:

int n = 0xbabebabe;
int * p ; 

int main()  // C语言的入口函数
{
        p =         
网站声明:本文,文章仅为传播更多信息之目的,如信息有误,请联系我们修改或删除,多谢。
© 版权声明
评论 抢沙发
加载中~
每日一言
不怕万人阻挡,只怕自己投降
Not afraid of people blocking, I'm afraid their surrender