bin、hex、elf、axf 文件的区别

1、bin 

  Bin 文件是最纯粹的二进制机器代码,或者说是 "顺序格式"。按照 assembly code 顺序翻译成 binary machine code,内部没有地址标记。Bin 是直接的内存映象表示,二进制文件大小即为文件所包含的数据的实际大小。 BIN 文件就是直接的二进制文件,一般用编程器烧写时从 00 开始,而如果下载运行,则下载到编译时的地址即可。可以直接在裸机上运行。
 

2.hex

Intel hex 文件常用来保存单片机或其他处理器的目标程序代码。它保存物理程序存储区中的目标代码映象。一般的编程器都支持这种格式。 就是机器代码的十六进制形式,并且是用一定文件格式的 ASCII 码来表示。

  HEX 文件由记录(RECORD)组成。在 HEX 文件里面,每一行代表一个记录。每条记录都由一个冒号 “:” 打头,其格式如下:

  :BBAAAATTHHHH...HHHHCC  

  BB: 字节个数。
  AAAA: 数据记录的开始地址,高位在前,低位在后。
  TT: Type
  00 数据记录,用来记录数据。
  01 记录结束,放在文件末尾,用来标识文件结束。
  02 用来标识扩展段地址的记录
  04 扩展地址记录 (表示 32 位地址的前缀)
  HHHH: 一个字 (Word) 的数据记录,高字节在前,低字节在后。TT 之后共有 BB/2 个字的数据 。
  CC: 占据一个 Byte 的 CheckSum
  举例分析:
  :020000040000FA
  :10000400FF00A0E314209FE5001092E5011092E5A3
  :00000001FF 

  分析如下:

  第 1 条记录长度为 0x02,LOAD OFFSET 为 0000,RECTYPE 为 04,说明该记录为扩展段地址记录。数据为 0000,校验和为 FA。从这个记录的长度和数据,我们可以计算出基地址为 0X0000。后面的数据记录都以此地址为基地址。  

  第 2 条记录长度为 0x10(16),LOAD OFFSET 为 0004,RECTYPE 为 00,说明该记录为数据记录。数据为 FF00A0E314209FE5001092E5011092E5,共 16 个字节,记录的校验和为 A3。此时的基地址为 0X0000,加上 OFFSET,这个记录里的 16BYTE 的数据的起始地址就是 0x0000 + 0x0004 = 0x0004. 其实际的数据只有 16 个 BYTE:FF00A0E314209FE5001092E5011092E5。
  第 3 条记录的长度为 00,LOAD OFFSET 为 0000,TYPE= 01,校验和为 FF。类型为 01,说明这个是一个 END OF FILE RECORD,标识文件的结尾。HEX 结束符一般以:00000001FF 结尾。

  简单总结一下这 2 种文件格式的区别:
  1、HEX 文件包含地址信息而 BIN 文件只包含数据本身,烧写或下载 HEX 文件时,一般不需要用户指定地址,因为 HEX 文件内部已经包含了地址信息。烧写 BIN 文件时则需要用户指定烧录的地址信息。
  2、HEX 文件是用 ASCII 码来表示二进制的数值。例如 8-BIT 的二进制数值 0x4E,用 ASCII 来表示就需要分别表示字符‘4’和字符‘E’,每个字符均需要一个字节,因此 HEX 文件至少需要 2 倍 BIN 文件的空间。
3.elf

  ELF(Executableand linking format)文件是 x86 Linux 系统下的一种常用目标文件 (objectfile) 格式,有三种主要类型:

  (1) 适于连接的可重定位文件 (relocatablefile),可与其它目标文件一起创建可执行文件和共享目标文件。
  (2) 适于执行的可执行文件 (executable file),用于提供程序的进程映像,加载到内存执行。
  (3) 共享目标文件 (shared object file), 连接器可将它与其它可重定位文件和共享目标文件连接成其它的目标文件,动态连接器又可将它与可执行文件和其它共享目标文件结合起来创建一个进程映像。 

  小结:可由 elf 文件转化为 hex 和 bin 两种文件,hex 也可以直接转换为 bin 文件,但是 bin 要转化为 hex 文件必须要给定一个基地址。而 hex 和 bin 不能转化为 elf 文件,因为 elf 的信息量要大。

4.axf

  Axf 文件由 ARM 编译器产生,除了包含 bin 的内容之外,还附加其他调试信息,这些调试信息加在可执行的二进制数据之前。调试时这些调试信息不会下载到 RAM 中,真正下载到 RAM 中的信息仅仅是可执行代码。因此,如果 ram 的大小小于 axf 文件的大小,程序是完全有可能在 ram 中调试的,只要 axf 除去调试信息后文件大小小于 ram 的大小即可。

  调试信息有以下功用:
  1、 可将源代码包括注释夹在反汇编代码中,这样我们可随时切换到源代码中进行调试。
  2、 我们还可以对程序中的函数调用情况进行跟踪 (通过 Watch & Call Stack Window 查看)。
  3、对变量进行跟踪 (利用 Watch & Call Stack Window)。
  调试信息虽然有用,但程序功能实现后,在目标文件和库中减少调试信息却是非常有益的。减少调试信息可减少目标文件和库大小、加快链接速度、减小最终镜象代码。以下几种方法可用来减少每个源文件产生的调试信息:
  1、避免在头文件中条件性使用 #define,链接器不能移除共用的调试部分,除非这些部分是完全一样的。
  2、更改 C/C++ 源文件,使 #included 包含的所有头文件有相同顺序。
  3、尽量使用数量较多的小头文件而不是较大的单一头文件,这有利于链接器获取更多的通用块。
  4、程序中最好只包含必须用到的头文件。避免重复包含头文件,可使用编译器选项 --remarks 来产生警告信息;

注意:

  (1)axf 和 elf 都是编译器生成的可执行文件。区别是:ADS 编译出来的是 AXF 文件。gcc 编译出来的是 ELF 文件。两者虽然很像,但还是有差别的。这是文件格式的差别,不涉及调试格式。

  (2)axf/elf 是带格式的映象,bin 是直接的内存映象的表示。

  (3)Linux OS 下,ELF 通常就是可执行文件,通常 gcc -o test test.c,生成的 test 文件就是 ELF 格式的,在 Linux Shell 下输入./test 就可以执行。在 Embedded 中,上电开始运行,没有 OS 系统,如果将 ELF 格式的文件烧写进去,包含一些 ELF 格式的东西,arm 运行碰到这些指令,就会导致失败,如果用 bin 文件,程序就可以一步一步运行。

你可能感兴趣的