汇编返回指令ret iret retf区别

这是 8086 汇编中三个最容易混淆的返回指令。它们的区别在于从栈上弹出什么数据 以及如何恢复 CPU 执行状态

核心区别一览表

指令 操作码 弹出字节数 弹出的内容 典型配对 使用场景
RET C3 2 IP CALL NEAR 段内返回
RETF CB 4 IPCS CALL FAR 段间返回
IRET CF 6 IPCSFLAGS INT n 中断返回

详细分析

1. RET (Return from Near Call)

操作:

复制代码
IP ← [SP]
SP ← SP + 2

特点:

  • 只恢复指令指针 IP

  • 不改变 CS(仍在同一代码段)

  • 不恢复 FLAGS

对应调用: CALL NEAR(段内调用)

示例:

cpp 复制代码
    CALL NEAR func    ; 压入 IP
    ...
func:
    RET               ; 弹出 IP,返回调用处

2. RETF (Return from Far Call)

操作:

cpp 复制代码
IP ← [SP]      ; 先弹出 IP
SP ← SP + 2
CS ← [SP]      ; 再弹出 CS
SP ← SP + 2

特点:

  • 恢复 IPCS(实现段间跳转)

  • 不恢复 FLAGS

对应调用: CALL FAR(段间调用)或手动 PUSH CS + PUSH IP + RETF

你的监控程序中的例子(源码第 552 行):

cpp 复制代码
522 C287 A108FF      MOV AX,[USER_CS]    ; AX = 0000H
523 C28A 50          PUSH AX            ; 压入 CS
524 C28B A106FF      MOV AX,[USER_IP]   ; AX = 0400H
525 C28E 50          PUSH AX            ; 压入 IP
...(恢复其他寄存器)
552 C2B2 CB          RETF               ; 弹出 IP=0400, 弹出 CS=0000
                                        ; 跳转到 0000:0400(用户程序)

3. IRET (Return from Interrupt)

操作:

cpp 复制代码
IP ← [SP]      ; 弹出 IP
SP ← SP + 2
CS ← [SP]      ; 弹出 CS
SP ← SP + 2
FLAGS ← [SP]   ; 弹出 FLAGS
SP ← SP + 2

特点:

  • 恢复 IPCSFLAGS

  • 通常还会恢复中断允许标志(IF)(因为 INT 指令会自动清除 IF)

对应调用: INT n(软件中断)或硬件中断

栈帧对比图

执行 CALL NEAR 后的栈

cpp 复制代码
执行 CALL func 前              执行 CALL func 后
SP → [旧数据]                  SP → [返回 IP(2 字节)]
                               SP+2 → [旧数据]

执行 CALL FAR 后的栈

cpp 复制代码
执行 CALL FAR func 前          执行 CALL FAR func 后
SP → [旧数据]                  SP → [返回 IP(2 字节)]
                               SP+2 → [返回 CS(2 字节)]
                               SP+4 → [旧数据]

执行 INT n 后的栈

cpp 复制代码
执行 INT n 前                  执行 INT n 后
SP → [旧数据]                  SP → [返回 IP(2 字节)]
                               SP+2 → [返回 CS(2 字节)]
                               SP+4 → [FLAGS(2 字节)]
                               SP+6 → [旧数据]

常见错误

RET 代替 IRET:会导致 FLAGS 没有被弹出,栈不平衡,返回地址错误

IRET 代替 RET:会多弹出 2 字节当作 FLAGS,导致 IP 和 CS 错位

RETF 代替 IRET:FLAGS 没有被恢复,中断标志可能错误

正确原则:用什么指令调用,就用对应的指令返回

  • CALL NEARRET

  • CALL FARRETF

  • INT nIRET

相关推荐
执迷不悟8231 天前
ARM--汇编指令
汇编·arm开发
Dlrb12112 天前
ARM指令集---汇编指令集的学习与应用:C程序与汇编的相互调用,处理器工作模式的改变等
汇编·arm开发·arm··arm指令集·汇编指令
学逆向的4 天前
汇编——函数
开发语言·汇编·网络安全
学逆向的4 天前
汇编——修改EIP的值
开发语言·汇编·网络安全
学逆向的8 天前
汇编——数据存储模式
开发语言·汇编·网络安全
学逆向的9 天前
汇编——内存
开发语言·汇编·算法·网络安全
学逆向的9 天前
汇编——位运算
开发语言·汇编·算法·网络安全
hai3152475439 天前
九章编译法----空间几何统一编译法
网络·汇编·人工智能·线性代数
想你依然心痛11 天前
自定义RTOS内核:从零实现上下文切换与任务调度——汇编、PendSV
java·开发语言·汇编·pendsv
hai31524754311 天前
九章空间几何对照直译法:通用芯片 / 定制专用芯片 编译适配规则
linux·汇编·bash