news 2026/5/28 22:46:08

8086/8088中断栈操作详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
8086/8088中断栈操作详解

1. 完整压栈过程(从中断触发到当前)

第一阶段:硬件自动压栈(中断响应时)

INT 1指令执行或单步中断触发时,CPU 自动按顺序压入:

顺序压入内容大小SP 变化
1FLAGS2 字节SP ← SP - 2
2CS2 字节SP ← SP - 2
3IP2 字节SP ← SP - 2

此时,IP在栈顶,SP指向IP的高字节(8086 小端模式)。

第二阶段:你的代码手动压栈(保存现场)

你的代码继续压入:

push ax ; 顺序 4 push bx ; 顺序 5 push cx ; 顺序 6 push dx ; 顺序 7 push si ; 顺序 8 push di ; 顺序 9 push ds ; 顺序 10 push es ; 顺序 11

2. 完整的堆栈内存布局

假设中断发生前的初始SP值为SP_initial,经过以上操作后:

内存地址(低地址在上,向下增长) ═══════════════════════════════════════════════════════ [SP_initial - 22] ← 当前 SP 指向这里 +-----------------+ | ES 低字节 | ← 最后压入(顺序 11) +-----------------+ | ES 高字节 | +-----------------+ | DS 低字节 | ← 顺序 10 +-----------------+ | DS 高字节 | +-----------------+ | DI 低字节 | ← 顺序 9 +-----------------+ | DI 高字节 | +-----------------+ | SI 低字节 | ← 顺序 8 +-----------------+ | SI 高字节 | +-----------------+ | DX 低字节 | ← 顺序 7 +-----------------+ | DX 高字节 | +-----------------+ | CX 低字节 | ← 顺序 6 +-----------------+ | CX 高字节 | +-----------------+ | BX 低字节 | ← 顺序 5 +-----------------+ | BX 高字节 | +-----------------+ | AX 低字节 | ← 顺序 4 +-----------------+ | AX 高字节 | +-----------------+ | IP 低字节 | ← 硬件自动压入(顺序 3) +-----------------+ | IP 高字节 | +-----------------+ | CS 低字节 | ← 硬件自动压入(顺序 2) +-----------------+ | CS 高字节 | +-----------------+ | FLAGS 低字节 | ← 硬件自动压入(顺序 1) +-----------------+ | FLAGS 高字节 | +-----------------+ [SP_initial] ← 原始栈顶 +-----------------+ | ... | +-----------------+

3. FLAGS 在堆栈中的位置

重要答案FLAGS位于堆栈中的偏移 +20处(相对于当前SP)。

3. FLAGS 在堆栈中的位置

重要答案FLAGS位于堆栈中的偏移 +20处(相对于当前SP)。

相对于当前 SP 的偏移量计算

内容相对于当前 SP 的偏移字节数
当前 SP 指向的位置0-
ES+22
DS+42
DI+62
SI+82
DX+102
CX+122
BX+142
AX+162
IP+182
CS+202
FLAGS+222

注意:堆栈是向下增长的,当前 SP 指向最低地址(栈顶)。FLAGS 在高地址处(更靠近原始栈顶)。

4. 如何访问堆栈中的 FLAGS

方法 1:通过 BP 访问(推荐)

int1_handler proc push bp ; 先保存 BP mov bp, sp ; BP 指向当前栈顶 ; 现在可以通过 [BP+偏移] 访问 ; [BP+24] 是 FLAGS(因为又多压了一个 BP) ; [BP+22] 是 CS ; [BP+20] 是 IP ; [BP+4] 是 AX 等

方法 2:直接计算偏移(不推荐,容易出错)

; 假设当前 SP 指向 ES 的高字节 ; FLAGS 在 [SP+22] mov ax, [sp+22] ; 读取 FLAGS

5. 完整的恢复过程(与压栈顺序相反)

中断返回前,必须按相反顺序恢复:

int1_handler proc ; ... 中断处理代码 ... ; 恢复现场(顺序相反) pop es ; 先弹出最后压入的 pop ds pop di pop si pop dx pop cx pop bx pop ax iret ; 自动弹出 IP → CS → FLAGS

6. 示意图:SP 变化轨迹

中断前: SP = 1000H ↓ 硬件压 FLAGS: SP = 0FFEH (1000-2) 硬件压 CS: SP = 0FFCH 硬件压 IP: SP = 0FFAH 压 AX: SP = 0FF8H 压 BX: SP = 0FF6H 压 CX: SP = 0FF4H 压 DX: SP = 0FF2H 压 SI: SP = 0FF0H 压 DI: SP = 0FEEH 压 DS: SP = 0FECH 压 ES: SP = 0FEAH ← 当前 SP

此时FLAGS[SP+22]=[0FEAH+16H]=[1000H-2]=[0FFEH],验证正确。

. 关键总结

问题答案
FLAGS 在堆栈中的位置当前 SP + 22(字节偏移)
为什么是 +22?因为压了 10 个用户寄存器(20 字节)+ IP(2) + CS(2) = 24 字节,FLAGS 在第 25-26 字节,从 0 计数偏移 22
如何访问 FLAGS?mov ax, [bp+24](如果用 BP 帧指针)
为什么要保存这么多寄存器?中断处理不能破坏任何寄存器,必须完整保存和恢复
8088 有 PUSHA 吗?没有,PUSHA 是 80186+ 才有的

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 22:46:05

【C++】零基础入门 · 第 10 节:结构体与类

在前面的章节中,我们学习了变量、数组、函数、指针和动态内存。这些都是 C++ 的基础构件,但随着程序变得越来越复杂,你会发现一个问题:相关的数据散落在各个变量里,传递和管理起来非常麻烦。比如要表示一个学生的信息(姓名、年龄、成绩),你得定义三个独立的变量,每次传…

作者头像 李华
网站建设 2026/5/28 22:44:21

项目介绍 MATLAB实现基于偏最小二乘回归(PLS)进行回归预测(含模型描述及部分示例代码)专栏近期有大量优惠 还请多多点一下关注 加油 谢谢 你的鼓励是我前行的动力 谢谢支持 加油 谢谢

MATLAB实现基于偏最小二乘回归(PLS)进行回归预测的详细项目实例项目背景介绍偏最小二乘回归,简称 PLS,是一种兼顾降维、特征提取与回归建模的统计学习方法,在高维、多共线、样本量有限、噪声干扰明显的真实工程场景中具有很高的实用价值。许多…

作者头像 李华
网站建设 2026/5/28 22:43:26

随机变形对模型训练结果的影响

0、结论1、全部随机变形时的训练结果2、80%随机变形时的训练结果3、60%随机变形时的训练结果4、40%随机变形时的训练结果5、20%随机变形时的训练结果6、0%随机变形时的训练结果

作者头像 李华
网站建设 2026/5/28 22:40:00

3D打印机改造笔式绘图仪:硬件组装、固件配置与G代码生成全攻略

1. 项目概述与核心思路拆解将一台闲置或常用的3D打印机改造为笔式绘图仪,这个想法听起来像是创客圈子里才会有的“疯狂”点子,但实际操作下来,你会发现它逻辑自洽,且极具实用价值。我手头这台Anycubic Kobra 2 Neo,作为…

作者头像 李华
网站建设 2026/5/28 22:39:25

2026年深圳市重点实验室组建资助项目形式审查要点

一、申请单位资质 1.申请单位是否是在深圳市(含深汕特别合作区)具有独立法人资格的高校、科研院所、医疗卫生机构、企业和社会组织或者是依法批准设立的其他机构。 相关凭证: (1)法定代表人身份证复印件; &…

作者头像 李华