交流
商城
MCN
登入
注册
首页
提问
分享
讨论
建议
公告
动态
发表新帖
发表新帖
6 实模式下的中断机制
分享
未结
0
2683
李延
LV6
2022-06-24
悬赏:20积分
# 1 什么是中断 https://zh.m.wikipedia.org/zh-hant/%E4%B8%AD%E6%96%B7 在计算机科学中,中断(英语:Interrupt)是指处理器接收到来自硬体或软体的信号,提示发生了某个事件,应该被注意,这种情况就称为中断。 通常,在接收到来自外围硬件(相对于中央处理器和内存)的异步信号,或来自软件的同步信号之后,处理器将会进行相应的硬件/软件处理。发出这样的信号称为进行中断请求(interrupt request,IRQ)。硬件中断导致处理器通过一个执行资讯切换(context switch)来保存执行状态(以程序计数器和程序状态字等寄存器信息为主);软件中断则通常作为CPU指令集中的一个指令,以可编程的方式直接指示这种执行资讯切换,并将处理导向一段中断处理代码。中断在计算机多任务处理,尤其是即时系统中尤为有用。这样的系统,包括运行于其上的操作系统,也被称为「中断驱动的」(interrupt-driven)。 # 2 中断分类 在 Intel 手册上 是这样描述的。  简单理解为: 处理器提供了两种中断程序执行的机制:中断和异常: - 中断:**CPU 提供了两种中断程序执行的机制,中断和异常**,比如点击一下鼠标、敲击一下键盘等。 - 异常:**异常是一个同步事件,是 CPU 在执行指令时检测到的反常条件**。比如除法异常、错误指令异常,缺页异常等。 其实两种殊途同归,相当于为我们的cpu提供一个异步通知的机制。 当中断或异常时是有信号的,处理器暂停当前程序或任务的执行,并切换到一个处理过程已专门编写用于处理中断或异常情况。处理器访问处理程序过程通过中断描述符表(IDT)中的一个条目。当处理程序完成对中断或异常,程序控制返回到中断的程序或任务。 # 3 中断向量表 操作系统的代码可以通过 **LIDT 指令**,将中断描述符表的地址放在这个寄存器里。 操作系统把这个的地址用 **LIDT** 指令放在 **IDTR 寄存器**就行了。在实模式下每16位为一个元素,保存的就是中断发生后需要跳转的地址 # 4 中断执行流程 **CPU 在收到一个中断号并且找到了中断描述符之后,究竟做了哪些事**? 其实就是将中断程序地址取出来,然后赋值给ip,使程序跳转到中断程序处执行。 当然,除了跳转外,cpu还帮助我们程序员做了好多额外的事情,包括: ***1.*** 如果发生了特权级转移,压入之前的堆栈段寄存器 SS 及栈顶指针 ESP 保存到栈中,并将堆栈切换为 TSS 中的堆栈。(后面保护模式详细说明) ***2.*** 压入标志寄存器 EFLAGS。 ***3.*** 压入之前的代码段寄存器 CS 和指令寄存器 EIP,相当于压入返回地址。 ***4.*** 如果此中断有错误码的,压入错误码 ERROR_CODE ***5.*** 结束(通过iret指令) # 5 cpu默认中断 cpu默认在发生一下异常时,触发如下中断:  # 6 示例 ## 6.1 使用中断 在Hello, World! 程序中,我们就使用了中断,`int 0x1301`。 它时bios定义的异常。 ## 6.2 自定义中断并调用 我们本节目标时是自己设置中断向量表,并触发中断,观察一下运行情况。 但应为我们修改了中断,所以没办法再使用bios自己的中断打印字符,所以这里我们只是debug观察代码的跳转 ```asm .code16 .global _start .equ BOOTSEG, 0x07c0 # original address of boot-sector _start: mov $BOOTSEG,%ax mov %ax,%es mov %ax,%ss mov %ax,%ds mov $0x400,%sp # 设置栈指针 cli #禁止中断发生, 我们下面将要改中断向量了,所以先吧中断禁止了 ## 设置中断向量表地址, lidt idt_48 # 设置0x00 中断 mov $0x0300,%bx mov $0x07c00,%ax add $int_err1,%ax mov %ax,(%bx) # 设置0x01 中断 mov $0x0304,%bx mov $0x07c00,%ax add $int_err2,%ax mov %ax,(%bx) sti int $0x0 int $0x1 ret int_err1: mov $1,%bx mov $19,%cx iret int_err2: mov $1,%bx mov $19,%cx iret idt_48: .word 0x0100 # 设置中断长度 .word 0x07f00,0 # 设置中断向量表地址 .org 510 boot_flag: .word 0xAA55 ``` 我们看到发生0x00 中断时, 代码跳转到了int_err1处:  发生0x01 中断时, 代码跳转到了int_err2处: 
回帖
消灭零回复
提交回复
热议榜
java 相关知识分享
8
好的程序员与不好的程序员
6
写给工程师的十条精进原则
5
spring boot以jar包运行配置的logback日志文件没生成
5
一步一步分析SpringBoot启动源码(一)
5
MockMvc测试
5
【吐槽向】是不是有个吐槽的板块比较好玩
4
logstash jdbc同步mysql多表数据到elasticsearch
3
IntelliJ IDEA 优质License Server
3
.gitignore忽略规则
3
SpringBoot启动源码分析
3
一步一步分析SpringBoot启动源码(三)
3
2
一步一步分析SpringBoot启动源码(二)
2
积分不够将无法发表新帖
2
官方产品
Meta-Boot - 基于MCN
MCN - 快速构建SpringBoot应用
微信扫码关注公众号