Hex 文件格式解析

Hex 文件格式解析

参考资料

Intel HEX File Format Keil

Intel HEX Wiki

格式

  • 以行为单位,每行以冒号开头,内容全部为16进制码(以ASCII码形式显示)
  • 在HEX文件里面,每一行代表一个记录。记录的基本格式为如表所示
冒号本行数据长度本行数据起始地址数据类型数据校验码
1 byte2 bytes1 byten byte1 byte

Hex文件格式解析

Start codeone character, an ASCII colon ‘:’
Byte count两个十六进制数字(一个十六进制数字对),表示数据字段中的字节数(十六进制数字对)。最大字节数为 255 (0xFF)。16 (0x10) 和 32 (0x20) 是常用的字节数。
Address四位十六进制数字,表示数据的 16 位起始内存地址偏移量。数据的物理地址是通过将此偏移量添加到先前建立的基地址来计算的,从而允许内存寻址超出 16 位地址的 64 KB 限制。默认为零的基地址可以通过各种类型的记录进行更改。基地址和地址偏移量始终表示为大端值。
Record type两个十六进制数字,0005,定义数据字段的含义。参考下文
Data一个由n个字节组成的数据序列,由 2n 个十六进制数字表示。一些记录省略了这个字段(n等于零)。数据字节的含义和解释取决于应用程序。
Checksumtwo hex digits, a computed value that can be used to verify the record has no errors.计算校验和前所有16进制码的累加和。

指令类型 Record type

指令类型Record type的值一般是00~05,这表示了,当前这行hex格式的数据,所代表的含义:

十六进制代码记录类型描述Example
00数据包含数据和该数据的16位起始地址。字节计数指定记录中的数据字节数。右侧显示的示例为0B (十一)个数据字节(61, 64, 64, 72, 65, 73, 73, 20, 67, 61, 70)位于以地址开头的连续地址 0010。:0B 0010 00 6164647265737320676170 A7
01文件结束每个文件在文件的最后一行必须恰好发生一次。数据字段为空(因此字节数为00),并且地址字段通常为 0000。:00 0000 01 FF
02扩展段地址数据字段包含一个16位的段基址(因此字节数始终为02)与80x86实模式寻址兼容。地址字段(通常为0000)被忽略。最近的段地址02记录乘以16,然后加到每个后续数据记录地址,以形成数据的物理起始地址。这允许寻址多达1 MB的地址空间。:02 0000 02 1200 EA
03起始段地址对于80x86处理器,请指定CS:IP寄存器的初始内容(即起始执行地址)。地址字段是0000,字节数始终为04,前两个数据字节是CS值,后两个是IP值。:04 0000 03 00003800 C1
04扩展线性地址允许32位寻址(最大4GiB)。记录的地址字段将被忽略(通常是0000),其字节数始终为02。两个数据字节(大字节序)为所有后续类型指定32位绝对地址的高16位00记录; 这些高位地址位适用于下一个04记录。类型的绝对地址00 通过组合最近的高16位地址位形成记录 04 用低16位的地址记录 00记录。如果是类型00 记录之前没有任何类型 04 记录,然后其高16位地址位默认为0000。:02 0000 04 FFFF FC
05起始线性地址地址字段是 0000(未使用),字节数始终为04。四个数据字节代表一个32位地址值(big-endian)。对于80386和更高版本的CPU,此地址将加载到EIP寄存器中。
(仅限 MDK-ARM)起始线性地址记录指定应用程序的起始地址。这些记录包含完整的线性 32 位地址。
:04 0000 05 000000CD 2A
扩展线性地址记录 (HEX386)

扩展线性地址记录也称为 32 位地址记录和 HEX386 记录。这些记录包含数据地址的高 16 位(位 16-31)。扩展线性地址记录总是有两个数据字节,如下所示:

1
:02000004FFFFFC

在哪里:

  • 02是记录中的数据字节数。
  • 0000是地址字段。对于扩展线性地址记录,此字段始终为 0000。
  • 04是记录类型 04(扩展的线性地址记录)。
  • FFFF是地址的高 16 位。
  • FC是记录的校验和,计算方式为
    01h + NOT(02h + 00h + 00h + 04h + FFh + FFh)。

读取扩展线性地址记录时,存储在数据字段中的扩展线性地址将被保存并应用于从 Intel HEX 文件读取的后续记录。线性地址保持有效,直到被另一个扩展地址记录改变。

数据记录的绝对内存地址是通过将记录中的地址字段与扩展线性地址记录的移位地址数据相加得到的。下面的例子说明了这个过程。

1
2
3
4
Address from the data record's address field      2462
Extended linear address record data field FFFF
--------
Absolute-memory address FFFF2462
扩展段地址记录 (HEX86)

扩展段地址记录(也称为 HEX86 记录)包含数据地址段的第 4-19 位。扩展段地址记录总是有两个数据字节,如下所示:

1
:020000021200EA

在哪里:

  • 02是记录中的数据字节数。
  • 0000是地址字段。对于扩展段地址记录,该字段始终为 0000。
  • 02是记录类型 02(扩展段地址记录)。
  • 1200是地址段。
  • EA是记录的校验和,计算方式为
    01h + NOT(02h + 00h + 00h + 02h + 12h + 00h)。

当读取扩展段地址记录时,存储在数据字段中的扩展段地址被保存并应用于从 Intel HEX 文件读取的后续记录。段地址保持有效,直到被另一个扩展地址记录改变。

数据记录的绝对内存地址是通过将记录中的地址字段添加到来自扩展段地址记录的移位地址数据中获得的。以下示例说明了此过程。

1
2
3
4
Address from the data record's address field     2462
Extended segment address record data field 1200
--------
Absolute memory address 00014462
起始线性地址记录(仅限 MDK-ARM)

起始线性地址记录指定应用程序的起始地址。这些记录包含完整的线性 32 位地址。起始线性地址记录总是有四个数据字节,如下所示:

1
:04000005000000CD2A

在哪里:

  • 04是记录中的数据字节数。
  • 0000是地址字段。对于起始线性地址记录,该字段始终为 0000。
  • 05是记录类型 05(起始线性地址记录)。
  • 000000CD是应用程序的 4 字节线性起始地址。
  • 2A是记录的校验和,计算方式为
    01h + NOT(04h + 00h + 00h + 05h + 00h + 00h + 00h + CDh)。

Start Linear Address 指定了 __main(pre-main)函数的地址,而不是通常在调用 SystemInit() 之后调用 __main 的启动代码的地址。奇数线性起始地址指定 __main 是为 Thumb 指令集编译的。

起始线性地址记录可以出现在 hex 文件中的任何位置。在大多数情况下,可以忽略此记录,因为它不包含对闪存进行编程所需的信息。

文件结束 (EOF) 记录

英特尔 HEX 文件必须以文件结束 (EOF) 记录结尾。此记录在记录类型字段中必须具有值 01。EOF 记录始终如下所示:

1
:00000001FF

在哪里:

  • 00是记录中的数据字节数。
  • 0000是数据在内存中的位置。文件尾记录中的地址是无意义的并且被忽略。地址 0000h 是典型的。
  • 01是记录类型 01(文件结束记录)。
  • FF是记录的校验和,计算方式为
    01h + NOT(00h + 00h + 00h + 01h)。

tip

  • 用Notepad++打开hex文件,会自动上色、换行

Hex 文件格式解析
https://www.oikiou.top/2021/d3f98b78/
作者
Oikiou
发布于
2021年9月24日
许可协议