|
|
@ -580,6 +580,65 @@ Intel64和IA-32架构定义与操作一组64位和128位包装(Packed)数据 |
|
|
|
### 6.4.1 Call and Return Operation for Interrupt or Exception Handling Procedures |
|
|
|
|
|
|
|
@翻译人:si |
|
|
|
6.4 使用CALL和RET指令调用程序 (CALLING PROCEDURES USING CALL AND RET) |
|
|
|
|
|
|
|
注:procedures译为代码,program译为程序 |
|
|
|
|
|
|
|
  CALL 指令允许代码控制跳转到当前代码段(近调用 near call)和不同程序代码段(远调用 far call)。近调用通常在当前运行程序或任务中提供代码访问。远调用通常访问操作系统代码或不同任务中的代码。参见第三章的 ”CALL-Call Procedure“ 。在 *Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A*的“Instruction Set Reference, A-L” 中有对CALL指令更深层次的描述。 |
|
|
|
|
|
|
|
  RET 指令也允许近或远的返回以匹配进或远版本的 CALL 指令。另外,RET 指令允许程序在返回时递增栈指针来释放栈上的参数。具体要在栈上释放多少字节决定于 RET 指令上的可选参数(n)。在 *Intel® 64 and* *IA-32 Architectures Software Developer’s Manual, Volume 2B* 的 ”Instruction Set Reference, M-U“ 中有对 RET 指令更详细的介绍。 |
|
|
|
|
|
|
|
6.4.1 Near CALL and RET Operation |
|
|
|
|
|
|
|
  当执行近调用时,处理器会做以下这些事情(参见图 6-2 ) |
|
|
|
|
|
|
|
1. 将 EIP 寄存器的当前值压到栈中。 |
|
|
|
如果影子栈(shadow stack)被启用而且置换值为非零,将 EIP 寄存器的当前值压入影子栈中。 |
|
|
|
2. 在 EIP 寄存器中加载被调用代码的偏移量。 |
|
|
|
3. 开始执行被调用的代码 |
|
|
|
|
|
|
|
当执行的近返回(near return)时,处理器会执行这些动作: |
|
|
|
|
|
|
|
1. 弹出栈顶的值(返回指令指针)到 EIP 寄存器中。 |
|
|
|
如果影子栈被启用,从影子栈弹出栈顶值(返回指令指针)如果与从栈中弹出的指令指针不同,处理器会报一个控制保护异常,错误码为NEAR-RET(#CP(NEAR-RET))。 |
|
|
|
2. 如果 RET 指令有一个可选的 n 参数,按 n 操作数指定的字节数递增栈指针以从栈中释放参数 。 |
|
|
|
3. 恢复调用代码的运行。 |
|
|
|
|
|
|
|
6.4.2 Far CALL and RET Operation |
|
|
|
|
|
|
|
  当执行远调用时,处理器会执行这些动作(见图6-2): |
|
|
|
|
|
|
|
1. 将 CS 寄存器的当前值压入栈中。 |
|
|
|
|
|
|
|
如果影子栈被启用: |
|
|
|
|
|
|
|
a. 临时内部保存 SPP 寄存器的当前值,将SPP与下一个8字节边界对齐。 |
|
|
|
|
|
|
|
b. 将 CS 寄存器的当前值压入影子栈。 |
|
|
|
|
|
|
|
c. 将 LIP(CS.base + EIP)的当前值压入影子栈。 |
|
|
|
|
|
|
|
d. 将 SSP 寄存器内部保存值压入影子栈。 |
|
|
|
|
|
|
|
2. 将 EIP 寄存器的当前值压入栈中。 |
|
|
|
|
|
|
|
3. 加载包含调用代码的段的段选择子到 CS 寄存器中。 |
|
|
|
|
|
|
|
4. 加载调用代码的偏移值到 EIP 寄存器中。 |
|
|
|
|
|
|
|
5. 开始执行调用代码的运行。 |
|
|
|
|
|
|
|
当执行远返回时,处理器会做下面这些事情: |
|
|
|
|
|
|
|
1. 弹出栈顶值(返回指令指针)到 EIP 寄存器中。 |
|
|
|
2. 弹出栈顶值(返回代码段的段选择子)到CS寄存器中。 |
|
|
|
如果启用了影子寄存器 |
|
|
|
a. 产生控制保护异常(#CP(FAR-RET/IRET))如果 SSP 没有对齐8字节。 |
|
|
|
b. 将影子栈在 SSP+8(LIP)地址的值 和SSP + 16(CS)的值与 从栈中弹出的 CS 和(CS.base + EIP)相比较。如果没有匹配,产生控制保护异常(#CP(FAR-RET/IRET)) |
|
|
|
c. 弹出栈顶值(返回代码的SSP)从影子栈到 SSP 寄存器中。 |
|
|
|
3. 如果返回指令有可选参数n,按 n 操作数递增栈指针 n 个数量的字节以从栈上释放参数。 |
|
|
|
4. 恢复调用代码的运行。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 第七章 Programming With General-Purpose Instructions |
|
|
|