From 14fe56a67bfda61aea9c75869fe3e43c713b9771 Mon Sep 17 00:00:00 2001 From: BaoZR <474234165@qq.com> Date: Mon, 13 Dec 2021 17:13:27 +0800 Subject: [PATCH] =?UTF-8?q?Update=20=E5=8D=B7=E4=B8=80=EF=BC=9A=E5=9F=BA?= =?UTF-8?q?=E6=9C=AC=E6=9E=B6=E6=9E=84.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../卷一:基本架构.md | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/Intel 手册中文版/卷一:基本架构.md b/Intel 手册中文版/卷一:基本架构.md index 29a4aff..f7019c4 100644 --- a/Intel 手册中文版/卷一:基本架构.md +++ b/Intel 手册中文版/卷一:基本架构.md @@ -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