ZHCADC5A June 2013 – June 2020
个性化例程 PR0、PR1 和 PR2 使用字节编码的指令序列来说明如何展开帧。前几条指令被封装到 EXTAB 第一个字的剩余三个字节中;附加指令被封装到后续字中。最后一个字中未使用的字节由“RET ”指令填充。
尽管指令是字节编码的,但它们始终封装成从 MSB 开始的 32 位字。因此,在小端字节序模式下,第一个展开指令将不会位于最低地址字节。
个性化例程 PR0 最多允许三条展开指令,所有这些指令都存储在第一个 EXTAB 字中。如果有三个以上的展开指令,则必须使用其他个性化例程之一。
对于 PR1 和 PR2,位 23-16 编码展开指令的额外 32 位字的数量,该数量可为 0。
表 9-2 总结了展开指令集。表格后面对每条指令进行了更详细的介绍。
编码 | 指令 | 说明 |
---|---|---|
0xxx xxxx | POP bitmask (R10, R9, R8, R7, R6, R5, R4) + RET | 恢复被调用者保存的寄存器并返回。 |
11kk kkkk | SP += (kkkkkk << 1) + 2 [0x02-0x80] | 递增,增量为一个小常数 |
1000 0001 kkkk .... | SP += (ULEB128 << 1) + 0x102 [0x102-max] | 递增,增量为大常数 |
1000 0000 0000 0000 | CANTUNWIND | 函数不能展开 |
所有其他位模式均保留。
以下各段详细说明了展开指令的解释。
POP + RET
POP+RET 指令指定一个位掩码,用于表示由此函数逻辑程序保存的寄存器。这些寄存器必须按顺序弹出,从 R4 开始并继续到 R10。完成后,不再有展开指令。如果位掩码中的位均未设置,则这只是一条 RET 指令。
小增量
k 的值从编码的低 6 位中提取。此指令可以使 SP 递增一个介于 0x8 到 0x200 之间的值,包括边界值。0x208 到 0x400 范围内的增量应该用这些指令中的两个来完成。
大增量
值 ULEB128 在 8 位操作码之后的字节中进行 ULEB128 编码。此指令可以将 SP 递增 0x408 或更大的值。增量小于 0x408 应使用 1 条或 2 条小增量指令实现。
CANTUNWIND
此指令指示函数不能展开,通常是因为它是中断函数。但是,中断函数仍然可以有 try/catch 代码,因此 EXIDX_CANTUNWIND 不适用。