Hex 文件格式解析
Hex 文件格式解析
参考资料
格式
- 以行为单位,每行以冒号开头,内容全部为16进制码(以ASCII码形式显示)
- 在HEX文件里面,每一行代表一个记录。记录的基本格式为如表所示
冒号 | 本行数据长度 | 本行数据起始地址 | 数据类型 | 数据 | 校验码 |
---|---|---|---|---|---|
1 byte | 2 bytes | 1 byte | n byte | 1 byte |
Start code | one character, an ASCII colon ‘:’ |
Byte count | 两个十六进制数字(一个十六进制数字对),表示数据字段中的字节数(十六进制数字对)。最大字节数为 255 (0xFF)。16 (0x10) 和 32 (0x20) 是常用的字节数。 |
Address | 四位十六进制数字,表示数据的 16 位起始内存地址偏移量。数据的物理地址是通过将此偏移量添加到先前建立的基地址来计算的,从而允许内存寻址超出 16 位地址的 64 KB 限制。默认为零的基地址可以通过各种类型的记录进行更改。基地址和地址偏移量始终表示为大端值。 |
Record type | 两个十六进制数字,00到05,定义数据字段的含义。参考下文 |
Data | 一个由n个字节组成的数据序列,由 2n 个十六进制数字表示。一些记录省略了这个字段(n等于零)。数据字节的含义和解释取决于应用程序。 |
Checksum | two 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 |
|
在哪里:
- 02是记录中的数据字节数。
- 0000是地址字段。对于扩展线性地址记录,此字段始终为 0000。
- 04是记录类型 04(扩展的线性地址记录)。
- FFFF是地址的高 16 位。
- FC是记录的校验和,计算方式为
01h + NOT(02h + 00h + 00h + 04h + FFh + FFh)。
读取扩展线性地址记录时,存储在数据字段中的扩展线性地址将被保存并应用于从 Intel HEX 文件读取的后续记录。线性地址保持有效,直到被另一个扩展地址记录改变。
数据记录的绝对内存地址是通过将记录中的地址字段与扩展线性地址记录的移位地址数据相加得到的。下面的例子说明了这个过程。
1 |
|
扩展段地址记录 (HEX86)
扩展段地址记录(也称为 HEX86 记录)包含数据地址段的第 4-19 位。扩展段地址记录总是有两个数据字节,如下所示:
1 |
|
在哪里:
- 02是记录中的数据字节数。
- 0000是地址字段。对于扩展段地址记录,该字段始终为 0000。
- 02是记录类型 02(扩展段地址记录)。
- 1200是地址段。
- EA是记录的校验和,计算方式为
01h + NOT(02h + 00h + 00h + 02h + 12h + 00h)。
当读取扩展段地址记录时,存储在数据字段中的扩展段地址被保存并应用于从 Intel HEX 文件读取的后续记录。段地址保持有效,直到被另一个扩展地址记录改变。
数据记录的绝对内存地址是通过将记录中的地址字段添加到来自扩展段地址记录的移位地址数据中获得的。以下示例说明了此过程。
1 |
|
起始线性地址记录(仅限 MDK-ARM)
起始线性地址记录指定应用程序的起始地址。这些记录包含完整的线性 32 位地址。起始线性地址记录总是有四个数据字节,如下所示:
1 |
|
在哪里:
- 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 |
|
在哪里:
- 00是记录中的数据字节数。
- 0000是数据在内存中的位置。文件尾记录中的地址是无意义的并且被忽略。地址 0000h 是典型的。
- 01是记录类型 01(文件结束记录)。
- FF是记录的校验和,计算方式为
01h + NOT(00h + 00h + 00h + 01h)。
tip
- 用Notepad++打开hex文件,会自动上色、换行