热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:汇编12:内中断

篇首语:本文由编程笔记#小编为大家整理,主要介绍了汇编12:内中断相关的知识,希望对你有一定的参考价值。内中断CPU可以在执行

篇首语:本文由编程笔记#小编为大家整理,主要介绍了汇编12:内中断相关的知识,希望对你有一定的参考价值。



内中断

CPU可以在执行完当前正在执行的指令之后,检测到从CPU外部或内部产生的一种特殊信息,并且可以立即对所接受到的信息进行处理。这种特殊信息一般称其为中断信息。中断就是CPU不再接着刚执行完的指令向下执行,而是转而去处理这个特殊信息。


内中断的产生

从CPU内部产生的中断信息被称为内中断。当下列情况发生时会产生内中断:

1、除法错误,如执行div指令时产生的除法溢出

2、单步执行

3、执行into指令

4、执行int指令

CPU根据中断类型码来区分不同的中断信息,中断类型码是一个字节型数据,可以表示256种中断信息的来源,产生中断信息的来源简称为中断源。上述四种情况下的中断类型码如下:

1、除法错误:0

2、单步执行:1

3、执行into指令:4

4、执行int指令:中断类型码为指令后的字节型立即数


中断处理程序和中断向量表

CPU收到中断信息后,需要对中断信息进行处理,用来处理中断信息的程序被称为中断处理程序。

转去执行中断处理程序需要让CS:IP指向该程序的入口,这个过程需要用到中断向量表。CPU用8位的中断类型码通过中断向量表找到相应的中断处理程序的入口地址,中断向量表在内存中保存,其中存放着256个中断源所对应的中断处理程序的入口:


技术图片

对于8086CPU,中断向量表指定放在内存地址0处,从0000:0000到0000:03FF的1024个单元中存放着中断向量表。一个表项中放着一个中断处理程序的入口地址,包含段地址和偏移地址,占用两个字,高地址字存放段地址,低地址字存放偏移地址。


中断过程

CPU在执行完中断处理程序后,应该返回原来的执行点继续执行下面的命令。所以在中断过程中应该将原来的CS和IP保存起来。

中断过程如下:

1、根据中断信息取得中断类型码

2、标志寄存器的值入栈(中断处理程序可能会修改标志寄存器,所以这里要保存起来准备恢复)

3、设置标志寄存器的第8位TF和第9位IF的值为0

4、CS的内容入栈

5、IP的内容入栈

6、从内存地址为中断类型码*4的位置取出两个字,组成中断处理程序的入口,设置IP和CS


中断处理程序和iret指令

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

1、保存用到的寄存器

2、处理中断

3、恢复用到的寄存器

4、用iret指令返回

iret指令相当于执行:

pop IP
pop CS
popf

相当于把执行中断处理程序之前保存的内容(CS:IP和标志寄存器)全部恢复了。


编程处理0号中断

如果我们debug以下程序:

mov ax,1000h
mov bh,1
div bh

就会发生除法溢出错误,可以看到当产生中断时,控制台显示信息“Divide overflow”,这就是系统对0号中断的处理。

我们考虑改变0号中断处理程序的功能,要让其在屏幕中间显示“overflow”,然后返回操作系统。

这个程序的步骤如下:

1、产生0号中断信息,引发中断过程,CPU将进行如下工作:

取得中断类型码0、标志寄存器入栈然后TF、IF设置为0、CS和IP入栈、CS:IP根据中断向量表的完成跳转,进而执行中断处理程序。

2、中断处理程序的步骤如下:

相关处理、向显示缓冲区发送字符串“overflow”,然后返回DOS。我们称这段程序为do0。这个do0程序应该放在0000:0200处,这段空间是中断向量表的空闲单元,不会有程序占用。确定了do0程序的位置,就应该调整中断向量表的表项,应该要将do0的段地址0存放在0000:0002字单元中,将偏移地址200H存放在0000:0000字单元中。

综上所述,程序的框架如下:

assume cs:code
code segment
start: do0安装程序
设置中断向量表
mov ax,4c00h
int 21h

do0: 显示字符串“overflow”
mov ax,4c00h
int 21h
code ends
end start

这个程序执行时do0程序是不执行的,只是为了能让中断程序找到do0程序。


安装程序和设置中断向量

我们可以用movsb指令来将do0的代码移动到0:200处:

start: mov ax,cs
mov ds,ax
mov si,offset do0 设置ds:si指向源地址
mov ax,0
mov es,ax
mov di,200h 设置es:di指向目的地址

mov cx,offset do0end-offset do0 设置传输长度
cld 设置传输方向
rep movsb

设置中断向量表
mov ax,0
mov es,ax
mov word ptr es:[0*4],200h
mov word ptr es:[0*4+2],0
mov ax,4c00h
int 21h

这里注意因为do0代码段的长度是可变的,所以这里用offset do0end-offset do0来代表代码的长度,减号是编译器识别的符号。


do0程序

程序如下:

do0: jmp short do0start
db "overflow!"
do0start: mov ax,cs
mov ds,ax
mov si,202h 设置ds:si指向字符串

mov ax,0b800h
mov es,ax
mov di,12*160+36*2 设置es:di指向显存空间的中间位置

mov cx,9 设置cx为字符串长度
s: mov al,[si]
mov es:[di],al
inc si
add di,2
loop s

mov ax,4c00h
int 21h
do0end:nop

这里要打印的字符串overflow也必须放在do0程序中,因为设置好中断程序后,这个程序随时都有可能执行,也就是说除了中断程序之外的数据都有可能被其他数据覆盖。


单步中断

我们在debug时如果使用t命令,CPU就能执行一条指令后,就显示各个寄存器的状态,这是因为CPU有一种机制被称为单步中断,当CPU执行完一条指令时,如果检测到标志寄存器中的TF位为1,则产生单步中断,引发中断过程,此时它的中断类型码为1.

debug就是因为将TF设置为1,使得CPU工作于单步中断方式下。在进入中断处理程序之前,TF值要设置为0,这是为了不让中断处理程序也引起中断导致无限中断。


不响应中断的特殊情况

有些情况下即使发生中断,CPU也不会响应。

其中之一就是执行完向ss寄存器传送数据的指令后,不会响应中断。这是因为ss和sp通常是连续设置完成的,如果ss设置完了之后sp还没设置就产生中断,这使中断时ss:sp指向错误的栈顶,让中断过程压入栈中的数据可能覆盖有用的数据。所以CPU在执行完设置ss的指令后,不响应中断,所以在编程的时候sp的设置应该紧跟ss之后,不宜离太远。


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • RouterOS 5.16软路由安装图解教程
    本文介绍了如何安装RouterOS 5.16软路由系统,包括系统要求、安装步骤和登录方式。同时提供了详细的图解教程,方便读者进行操作。 ... [详细]
  • IB 物理真题解析:比潜热、理想气体的应用
    本文是对2017年IB物理试卷paper 2中一道涉及比潜热、理想气体和功率的大题进行解析。题目涉及液氧蒸发成氧气的过程,讲解了液氧和氧气分子的结构以及蒸发后分子之间的作用力变化。同时,文章也给出了解题技巧,建议根据得分点的数量来合理分配答题时间。最后,文章提供了答案解析,标注了每个得分点的位置。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文介绍了2020年计算机二级MSOffice的选择习题及答案,详细解析了操作系统的五大功能模块,包括处理器管理、作业管理、存储器管理、设备管理和文件管理。同时,还解答了算法的有穷性的含义。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 本文讨论了编写可保护的代码的重要性,包括提高代码的可读性、可调试性和直观性。同时介绍了优化代码的方法,如代码格式化、解释函数和提炼函数等。还提到了一些常见的坏代码味道,如不规范的命名、重复代码、过长的函数和参数列表等。最后,介绍了如何处理数据泥团和进行函数重构,以提高代码质量和可维护性。 ... [详细]
author-avatar
莫小北
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有