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