【计算机组成原理】 CALL与RET指令详解

在计算机组成原理中,CALL和RET指令是实现程序调用和返回的核心指令。它们配合栈(Stack)的使用,实现了子程序的调用与返回机制。本文将从指令功能、执行过程、栈帧变化等方面进行详细讲解,帮助理解这一重要的计算机体系结构概念。

一、CALL指令(调用指令)

1. 指令功能

CALL指令用于调用子程序(或称为过程、函数)。其执行过程包含两个主要步骤:

① 将当前指令的下一条指令地址(返回地址)压入栈中保存

② 将程序计数器PC(或CS:IP)设置为子程序的入口地址,跳转到子程序执行

2. 指令格式

指令格式

操作数

说明

CALL NEAR

近调用(段内)

在同一代码段内调用,只保存IP

CALL FAR

远调用(段间)

跨代码段调用,保存CS和IP

CALL reg

寄存器间接调用

子程序地址在寄存器中

CALL mem

存储器间接调用

子程序地址在内存单元中

3. 执行过程详解

以16位x86汇编的近调用(NEAR CALL)为例,指令执行过程如下:

步骤

操作描述

SP ← SP - 2 (栈指针减2,准备压入返回地址)

[SS:SP] ← IP (将当前IP值压入栈顶)

IP ← 子程序入口地址 (跳转到子程序)

对于远调用(FAR CALL),还需要额外保存CS寄存器:

• 先压入CS,再压入IP

• 然后分别加载新的CS和IP值

二、RET指令(返回指令)

1. 指令功能

RET指令用于从子程序返回到调用者。其执行过程与CALL相反,从栈中弹出返回地址并恢复执行。

2. 指令格式

指令格式

操作数

说明

RET

无操作数

近返回,只弹出IP

RET n

立即数n

近返回并释放n个字节的参数

RET

远返回

先弹出IP,再弹出CS

3. 执行过程详解

以16位x86汇编的近返回(NEAR RET)为例,指令执行过程如下:

步骤

操作描述

IP ← [SS:SP] (从栈顶弹出返回地址到IP)

SP ← SP + 2 (栈指针加2,释放返回地址空间)

继续执行CALL之后的指令

对于带立即数的RET n指令,执行完上述步骤后,还会执行:

• SP ← SP + n (释放栈中的参数)

三、栈帧变化示例

以下是一个完整的子程序调用过程中栈的变化示例:

执行阶段

栈状态(从顶到底)

说明

调用前

[空栈或已有数据]

栈指针SP指向栈顶

CALL执行后

返回地址 [原栈内容]

返回地址被压入栈顶

子程序执行

局部变量 返回地址 [原栈内容]

子程序可能在栈中分配局部变量

RET执行前

返回地址 [原栈内容]

清理局部变量后,栈顶恢复为返回地址

RET执行后

[原栈内容]

返回地址弹出,程序回到调用处

四、CALL与RET指令对比

对比项

CALL指令

RET指令

功能

调用子程序

从子程序返回

栈操作

压入返回地址(SP减小)

弹出返回地址(SP增大)

PC变化

跳转到子程序入口

恢复到调用处下一条指令

执行顺序

先执行

后执行(与CALL配对)

嵌套调用

支持多层嵌套

按后进先出顺序返回