8086中断系统——《x86汇编语言:从实模式到保护模式》读书笔记04

2023-05-16

80X86中断系统

  • 能够处理256个中断
  • 用中断向量号0~255区别
  • 可屏蔽中断还需要借助专用中断控制器Intel 8259A实现优先权管理

1、中断的分类

中断可以分为内部中断和外部中断。

(1)内部中断

  • 除法错中断
  • 指令中断
  • 溢出中断
  • 单步中断
  • 断点中断

(2)外部中断

  • 非屏蔽中断
  • 可屏蔽中断

如果觉得上面的分类太抽象,那么下面的图会给你直观的印象。

中断框图

通过这张图,我们可以明白,内部中断是在处理器内部产生。外部中断是通过两个信号线(NMI和INTR)引入处理器内部的。

2.内部中断

(1)除法错中断

在执行除法指令时,若除数为0或商超过了寄存器所能表达的范围,则产生一个向量号为0的内部中断,称为除法错中断。

例如:

mov bl,0

idiv bl ;除数BL=0,产生除法错中断

再比如:

mov ax,200h

mov bl,1

div bl ;商=200H,不能用AL表达,产生除法错中断

(2)指令中断

在执行中断调用指令INT n时产生的一个向量号为n(0 ~ 255)的内部中断,称为指令中断。

(3)溢出中断

在执行溢出中断指令INTO时,若溢出标志OF为1,则产生一个向量号为4的内部中断,被称为溢出中断。

(4)单步中断

CPU在执行完一条指令之后,如果检测到标志寄存器的TF位为1,则产生单步中断,单步中断的向量号为1.

(5)断点中断

主要用在程序调试中,向量号为3,利用“int3(指令机器码为0xcc)”这条指令设置断点,目的是显示断点前程序的执行结果。

注意:内部中断不受标志寄存器IF位的影响。

3.外部中断

(1)非屏蔽中断

通过非屏蔽中断请求信号向微处理器提出的中断请求,微处理器无法禁止,将在当前指令执行结束予以响应,这个中断被称为非屏蔽中断。

非屏蔽中断的向量号为2,非屏蔽中断请求信号为NMI

非屏蔽中断主要用于处理系统的意外或故障。例如:电源掉电前的数据保护,存储器读写错误的处理。

(2)可屏蔽中断

通过INTR引脚引入CPU,只有当中断允许标志位IF=1时,才能被CPU响应。通过8259A,一个系统中可有多个可屏蔽中断。

4.实模式下的中断向量表

(1)中断向量

中断向量就是中断服务程序的入口地址。它有两部分组成:

  • 中断服务程序所在段的段基址(2个字节)
  • 中断服务程序入口的偏移地址(2个字节)

(2)中断向量表

每个中断向量占4个字节,256种中断向量总共占用1024字节。在8086系统中,所有的中断向量按类型码存放于内存的最低地址(00000H~003FFH)的1K单元中。存放中断向量的这1K单元称为中断向量表。

中断向量在中断向量表中的位置=中断类型号×4

N*4的字单元存放偏移地址;

N*4+2的字单元存放段基址。

5.中断类型号的获取

(1)对于除法出错,单步中断,不可屏蔽中断NMI,断点中断和溢出中断,CPU分别自动提供中断类型号0~4。

(2)对于用户自己确定的软件中断INT n,类型号由n决定。

(3)对外部可屏蔽中断INTR,CPU从可编程中断控制器8259A中获得中断类型号。

说明:

8086有两个引脚可以接收外部的中断请求:INTR和NMI

  • 当NMI(非屏蔽中断请求)引脚上出现上升沿信号时,CPU立即无条件(不执行中断响应周期,不受标志寄存器IF位的影响)地转入"2号中断处理程序"。
  • 当INTR(可屏蔽中断请求)引脚上出现高电平信号时,若IF=0,CPU不响应中断请求。若IF=1,CPU响应中断请求。CPU响应中断时,首先执行"中断响应周期",以便从中断控制器8259获得中断类型码,然后根据中断类型码转入相应的中断处理程序。

中断响应周期由两个总线周期构成

1.第一个总线周期

CPU向外设发出一个低电平的中断应答信号INTA*,表示已经接受申请,要求外设传送中断向量号

2.第二个总线周期

外设传送中断向量号,CPU在T4的下降沿采样数据总线,读入外设传送来的中断向量号(如下图)

总线周期

6.中断过程

(1)中断请求

中断源向CPU发出请求中断信号。中断信号将被锁存,直到CPU响应中断后,中断请求信号才被清除。

(2)中断响应

CPU在执行每条指令的最后一个时钟周期检测中断请求信号。若发现中断请求信号有效,在允许中断的条件下,CPU响应中断。

响应中断的过程可以总结为:

  • 取得中断类型码N;
  • pushf
  • TF=0,IF=0
  • push CS
  • push IP
  • IP=N*4, CS=N*4+2,;转中断服务程序

7.中断处理程序和iret指令

中断处理程序的编写方法和子程序比较相似,下面是常规的步骤:

(1)保存用到的寄存器

(2)处理中断

注意:由于IF标志被设置为0,在中断处理中,处理器将不再响应硬件中断。如果希望更高优先级的中断嵌套,可以在编写中断处理程序时,适时用sti指令开放中断。

(3)恢复用到的寄存器

(4)用iret指令返回

iret指令的功能可以用汇编语法描述为:

pop IP

pop CS

popf

需要说明的是:中断向量表的建立和初始化工作是由BIOS在计算机启动时完成的。BIOS为每个中断号填写入口地址,因为它不知道多数中断处理程序的位置,所以一律将它们指向同一个入口地址,在那里只有一条指令:iret. 也就是说,当这些中断发生时,只做一件事情——立即返回。当计算机启动后,操作系统和用户程序再根据自己的需要,修改某些中断的入口地址,使它指向自己的代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

8086中断系统——《x86汇编语言:从实模式到保护模式》读书笔记04 的相关文章

  • 问题:gcc 从我的 C++ 生成的程序集

    编译这段代码 int main return 0 using gcc S filename cpp 生成此程序集 file heloworld cpp text globl main type main function main LFB0
  • 汇编语言中数组的冒泡排序

    我需要对一个无组织的数组进行冒泡排序 其中包含从最大到最小的 7 个整数 因此它看起来像 9 6 5 4 3 2 1 我通过编译器运行我的代码 它说 我不明白这段代码有什么问题 code segment assume ds code cs
  • 算术恒等式和 EFLAGS

    因为 x not x 1 意味着 a b a not b 1 那么 sub rax rcx 相当于 mov temp rcx not temp add rax temp add rax 1 其中 temp 是一些被认为是易失性的寄存器 换句
  • 计算 Amd Zen 2 处理器上的 L3 缓存访问事件

    我试图找出与 perf stat 命令一起使用的事件来计算 AMD Zen 2 处理器上的 L3 缓存访问次数 根据 PPR http developer amd com wordpress media 2017 11 54945 PPR
  • 如何在汇编器中实现相对 JMP (x86)?

    在为 x86 平台构建汇编程序时 我遇到了一些编码问题JMP操作说明 OPCODE INSTRUCTION SIZE EB cb JMP rel8 2 E9 cw JMP rel16 4 because of 0x66 16 bit pre
  • x86 分页如何工作?

    这个问题旨在填补有关该主题的优质免费信息的真空 我相信一个好的答案将适合一个大的 SO 答案 或者至少适合几个答案 主要目标是为初学者提供足够的信息 以便他们可以自己阅读本手册 并能够理解与分页相关的基本操作系统概念 建议指南 answer
  • x86 汇编中 cmove 指令的用途?

    反汇编可执行文件时我遇到了cmove操作说明 我已经在互联网上搜索过 但我只发现这是一个有条件的移动 如果源和目的地相等mov发生 我还不明白为什么我需要它 因为它不会改变操作数 它的目的是什么 The CMOVcc指令不比较源和目标 它们
  • x86 实模式下的段大小

    我对实模式下段的大小有一个疑问 因为它们不能超过 64K 但可以小于那个 http support microsoft com kb 120069 我的问题是这些段大小和基地址是如何初始化的 就像保护模式下有 GDT 和 LDT 一样 实模
  • 跨 AVX 通道的最佳方式是什么?

    有些问题具有类似的标题 但我的问题涉及其他地方未涵盖的一个非常具体的用例 我有 4 个 128d 寄存器 x0 x1 x2 x3 我想将它们的内容重新组合在 5 个 256d 寄存器 y0 y1 y2 y3 y4 中 以准备其他计算 on
  • gcc 如何知道内联汇编中使用的寄存器大小?

    我有内联汇编代码 define read msr index buf asm volatile rdmsr d buf 1 a buf 0 c index 使用该宏的代码 u32 buf 2 read msr 0x173 buf 我发现反汇
  • 如何获取 VESA BIOS 信息

    我正在跟踪Phil Opp 教程 https os phil opp com 关于用 Rust 编写一个操作系统 在稍微尝试了一下之后 我想在屏幕上显示真实的图形 我发现我应该从使用带有 VESA 的线性帧缓冲区开始 我在 osdev or
  • 为什么 SSE 对齐读取 + 随机播放在某些 CPU 上比未对齐读取慢,而在其他 CPU 上则不然?

    在尝试优化有限差分代码所需的未对齐读取时 我更改了未对齐的负载 如下所示 m128 pm1 mm loadu ps H k 1 进入这个对齐的读取 随机播放代码 m128 p0 mm load ps H k m128 pm4 mm load
  • 这段汇编语言代码是什么意思?

    我是一名学生 刚刚开始学习汇编语言 为了更好地理解它 我只是用 C 写了一个简短的代码并将其转换为汇编语言 奇怪的是我有点听不懂 代码是 include
  • 如何让c代码执行hex机器代码?

    我想要一个简单的 C 方法能够在 Linux 64 位机器上运行十六进制字节码 这是我的 C 程序 char code x48 x31 xc0 include
  • 减法进位标志

    我正在使用 MASM32 有了这个代码 mov eax 5 sub eax 10 CF 状态标志将被设置 但使用我的铅笔和纸 我实际上看到 MSB 没有任何进位 是的 我知道从较少的数字中减去大的数字集CF 但我想知道为什么 因为使用这段代
  • 在 x86-64 CPU 上通过交叉修改代码重现意外行为

    Question 对于可能在 x86 或 x86 x64 系统上触发意外行为的交叉修改代码有哪些想法 在这些系统中 交叉修改代码中的所有操作均已正确完成 但在执行处理器之前执行序列化指令除外修改代码 如下所述 我有一个 Core 2 Duo
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • Intel 64 和 IA-32 上的 MESI 有何意义

    MESI 的要点是保留共享内存系统的概念 然而 对于存储缓冲区 事情就变得复杂了 一旦数据到达 MESI 实现的缓存 下游内存就会保持一致 然而 在此之前 每个核心可能对内存位置 X 中的内容存在分歧 具体取决于每个核心的本地存储缓冲区中的
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • 这种没有推送寄存器的交换有多安全?

    我对汇编非常陌生 下面的代码应该通过两个不同的函数交换两个整数 首先使用swap c然后使用swap asm 但我怀疑 我是否需要push 我的意思是保存 汇编代码之前寄存器的每个值和pop稍后 就在返回之前 main 换句话说 如果我返回

随机推荐