内中断---汇编学习笔记
内中断
“中断信息”是要求CPU马上进行某种处理,并向所要进行的该种处理提供了必备的参数的通知信息。
12.1 内中断的产生
当CPU内部有下面的情况发生的时候,将产生相应的中断信息。
- 除法错误
- 单步执行
- 执行into指令
- 执行int指令
8086CPU用称为中断类型码的数据来标识中断信息的来源。中断类型码为一个字节型数据,可以表示256种中断信息的来源。
- 除法错误:0
- 单步执行:1
- 执行into指令:4
- 执行int指令:该指令的格式为
int n
,指令中的n为字节型立即数,是提供给CPU的中断类型码。
12.2 中断处理程序
CPU收到中断信息后,需要对中断信息进行处理。而如何对中断信息进行处理,可以由我们编程决定。
CPU的设计者必须在中断信息和其处理程序的入口地址之间建立某种联系,使得CPU根据中断信息可以找到要执行的处理程序。
12.3 中断向量表
中断向量表的内存中保存,其中存放着256个中断源所对应的中断处理程序的入口,如图。
可见,CPU只要知道中断类型码,就可以将中断类型码作为中断向量表的表项号,定位相应的表项,从而得到中断处理程序的入口地址。
中断向量表在内存中存放,对于8086CP机,中断向量表指定放在内存地址0处。从内存0000:0000到0000:03FF的1024个单元中存放着中断向量表。
对于8086CPU,这个入口地址包括段地址和偏移地址,所以一个表项占两个字,高地址字存放段地址,低地址字存放偏移地址。
检测点 12.1
(1)用Debug查看内存,情况如下:
0000:0000 68 10 A7 00 8B 01 70 00-16 00 9D 03 8B 01 70 00
则3号中断源对应的中断处理程序入口地址为:0070:018B。
(2)存储N号中断源对应的中断处理程序入口的偏移地址的内存单元的地址为:0000:N*4.
存储N号中断源对应的中断处理程序入口的段地址的内存单元的地址为:0000:N*4+2.
12.4 中断过程
从上面的讲解中,我们知道,可以用中断类型码,在中断向量表中找到中断处理程序的入口。找到这个入口地址的最终目的是用它设置CS和IP,使CPU执行中断处理程序。用中断类型码找到中断向量,并用它设置CS和IP,这个工作是由CPU的硬件自动完成的。CPU硬件完成这个工作的过程被称为中断过程。
下面是8086CPU在收到中断信息后,所引发的中断过程。
- (从中断信息中)取得中断类型码
- 标志寄存器的值入栈(因为在中断过程中要改变标志寄存器的值,所以先将其保存在栈中)
- 设置标志寄存器的第8位TF和第9位IF的值为0(这一步的目的后面将介绍)
- CS的内容入栈
- IP的内容入栈
- 从内存地址为中断类型码∗4中断类型码∗4中断类型码*4和中断类型码∗4+2中断类型码∗4+2中断类型码*4+2的两个字单元中读取中断处理程序的入口地址设置IP和CS
更简洁的描述中断过程,如下:
- 取得中断类型码N
- pushf
- TF=0,IF=0
- push CS
- push IP
- (IP)=(N∗4),(CS)=(N∗4+2)(IP)=(N∗4),(CS)=(N∗4+2)(IP)=(N*4),(CS)=(N*4+2)
12.5 中断处理程序和iret指令
CPU随时都可能只想中断处理程序,所以中断处理程序必须一直存储在内存某段空间中。而中断处理程序入口地址,即中断向量,必须存储在对应的中断向量表表项中。
中断处理程序的编写方法和子程序的比较相似,下面是常规的步骤:
- 保存用到的寄存器
- 处理中断
- 恢复用到的寄存器
- 用iret指令返回
iret指令的功能用汇编语法描述为:
pop IP
pop CS
popf
12.6 除法错误中断的处理
当CPU执行div发生了除法溢出错误,将产生中断类型码为0的中断信息,CPU将检测到这个信息,然后引发中断过程,转去执行0号中断所对应的中断处理程序。
12.7 编写处理0号中断
这里略过,自己看,内容很细致。
12.8 安装
其实就是将代码复制到程序的某个地方,这里也略过!贴上代码。
assume cs:code
code segment
start:mov ax,csmov ds,axmov si,offset do0 ;设置ds:si指向源地址mov ax,0mov es,axmov di,200h ;设置es:di指向的目的地址mov cx,offset do0end-offset do0 ;设置cx为传输长度cld ;设置传输方向为正rep movsb ;复制设置中断向量表mov ax,4c00hint 21hdo0:显示字符串"overflow!"mov ax,4c00hint 21h
do0end:nop
code ends
end start
12.9 do0
显示字符串”overflow!”的子程序。不能够再去一个data的数据区,因为可能会被覆盖,所以应该如下:
12.10 设置中断向量
最重要点的一点:
mov ax,0
mov es,ax
mov word ptr es:[0*4],200h ;低地址字
mov word ptr es:[0*4+2],0 ;高地址字
12.11 单步中断
基本上,CPU在执行完一条指令之后,如果检测到标志寄存器的TF位为1,则产生单步中断,引发中断过程。单步中断的中断类型码为1,则它所引发的中断过程如下。
- 取得中断类型码1
- 标志寄存器入栈,TF、IF设置为0
- CS、IP入栈
- (IP)=(1∗4),(CS)=(1∗4+2)(IP)=(1∗4),(CS)=(1∗4+2)(IP)=(1*4),(CS)=(1*4+2)
注意,第2步很重要,因为如果不将TF位置0,则将陷入一个永远不能结束的循环。因为单步中断将引发单步中断的中断程序,而单步中断的中断程序将引发单步中断程序中的中断程序…
于是中断过程如下:
- 取得中断类型码N
- 标志寄存器入栈,TF=0、IF=0
- CS、IP入栈
- (IP)=(N∗4),(CS)=(N∗4+2)(IP)=(N∗4),(CS)=(N∗4+2)(IP)=(N*4),(CS)=(N*4+2)
12.12 响应中断的特殊情况
一般情况下,CPU在执行完当前指令后,如果检测到中断信息,就响应中断程序,引发中断过程。可是,在有些情况下,CPU在执行完当前指令后,即便是发生中断,也不会响应。
比如,在执行完向ss寄存器传送数据的指令后,即便发生中断,CPU也不会响应。这样做的主要原因是,ss:sp联合指向栈顶,而对它们的设置应该连续完成。如果执行完设置ss的指令后,CPU响应中断,引发中断过程,要在栈中压入标志寄存器、CS和IP的值。而ss改变,ss:sp指向的不是正确的栈顶,将引发错误。所以CPU在执行完设置ss的指令后,不响应中断。这给连续设置ss和sp指向正确的栈顶提供了一个时机。即,我们应该利用这个特性,将设置ss和sp的指令连续存放,使得设置sp的指令紧接着设置ss的指令执行,而在此之间,CPU不会引发中断过程。
实验12 编写0号中断的处理程序
分析:
assume cs:codesgcodesg segmentstart:ds:[si]是源地址0:200是目的地址cx是长度rep movsbmov ax,0mov es,axmov word ptr es:[0*4],200hmov word ptr es:[0*4],0mov ax,10div 0mov ax,4c00hint 21hdo0:db "divide error!"do0start:在屏幕中间显示"divide error!"mov ax,4c00hint 21hdo0end:nopcodesg ends
end start
实际代码:
assume cs:codesgcodesg segmentstart:mov ax,csmov ds,axmov si,offset do0 ;源地址mov ax,0mov es,axmov di,200h ;目的地址mov cx,offset do0end-offset do0 ;长度cld ;方向rep movsb ;安装mov ax,0mov es,axmov word ptr es:[0*4],200hmov word ptr es:[0*4+2],0 ;设置中断向量表mov ax,10mov dx,0div dxmov ax,4c00hint 21hdo0:jmp short do0startdb "divide error!" ;字符串do0start:mov ax,csmov ds,axmov si,202hmov ax,0b800hmov es,axmov di,12*160+36*2mov cx,13s:mov al,[si]mov es:[di],alinc siadd di,2loop s ;显示字符串mov ax,4c00h ;退出程序int 21hdo0end:nopcodesg ends
end start
实验结果:
内中断---汇编学习笔记相关推荐
- GNU C内嵌汇编学习笔记
前文所述,只是针对汇编格式的整理,本文将使用coreboot项目代码对其进行实例化.以方便.清晰了解到如何在C语言里使用内嵌汇编的方法.同样地,网络上也有众多文章涉及到这方面,所以本文更多是归纳总结. ...
- 外中断---汇编学习笔记
外中断 要及时处理外设的输入,显然需要解决两个问题: 外设的输入随时可能发生,CPU如何得知? CPU从何处得到外设的输入? 15.1 接口芯片和端口 外设的输入不直接送入内存和CPU,而是送入相关的 ...
- 汇编学习笔记——汇编指令
目录 汇编指令 nop指令 mov.add.sub指令 adc.sbb指令 and.or指令 移位指令 逻辑左/右移指令 循环左/右移指令 算术左/右移指令 带进位循环左/右移指令 inc指令 pus ...
- 汇编学习笔记——伪指令
目录 伪指令 段定义 结束标记 段关联标记 数据定义 标号 offset指令 seg指令 地址标号 数据标号 代码分段 程序标识 多文件系统 字符输入 重复定义 注释 重复汇编伪指令 伪指令汇总 伪指 ...
- 汇编学习笔记:对抗反汇编实验2019092801
汇编学习笔记:对抗反汇编实验2019092801 实验描述 实验环境 实验过程 实验结论 实验描述 使用相连的jz和jnz指令跳转到紧接着jnz指令的call指令的第二个字节.call指令实际上无效. ...
- 嵌入式linux 添加中断,《嵌入式linux应用程序开发完全手册》中断控制器操作(外部中断)学习笔记...
<嵌入式linux应用程序开发完全手册>中断控制器操作(外部中断)学习笔记 一.ARM中断体系 当一个"异常"发生时,或者说当收到一个中断触发信号时,ARM9将会自动完 ...
- [ARM-assembly]-ARM ASM内联汇编学习
★★★个人博客导读首页-点击此处 ★★★ 格式 __asm__ qualifiers ( // 汇编代码部分: OutputOperands //在内联汇编代码中被修改的变量列表: InputOper ...
- 寄存器---汇编学习笔记
第二章 寄存器 2.0 寄存器的绪论 一个典型的CPU由运算器.控制器.寄存器(CPU工作原理)等器件构成.内部总线实现 CPU 内部各个器件之间的联系,外部总线实现CPU和主板其他器件的联系. 在C ...
- 使用BIOS进行键盘输入和磁盘读写---汇编学习笔记
汇编笔记 使用BIOS进行键盘输入和磁盘读写 17.1 int 9中断例程对键盘输入的处理 17.2 使用int 16h中断例程读取键盘缓冲区 17.3 字符串的输入 17.4 应用int 13h中断 ...
最新文章
- JAXB--@XmlElementWrapper注解和泛型一起使用
- linux数组删除数据,JavaScript在数组的循环中删除元素
- 【opencv+机器学习】error C3083: 'ml': the symbol to the left of a '::' must be a type问题原因
- mysql列目录_mysql列直接存储图片路径
- 多元化思维其二:“马太效应”之道
- Vue.js2.0开发环境搭建(三)
- 梯度与散度与拉普拉斯算子
- 禅道类似软件_软件测试工程师都在用哪些测试工具
- python坦克大战小游戏,打包为exe文件
- idea视图化配置html页面,IntelliJ IDEA:配置JavaScript库
- Nokia PC 套件版本及在不同Windows 上的安装问题
- [渝粤教育] 西南科技大学 财务会计 在线考试复习资料(3)
- 2060显卡驱动最新版本_Ubuntu 18.04 安装 NVIDIA 显卡驱动
- C3: 基金名称末尾 A 和 C 的区别
- OpenCV-Python教程:阈值化(threshold,adaptiveThreshold)
- Latex各种箭头符号总结
- SBUS转485增程方案,SBUS控制远程机器人方案
- Javascript--04 JavaScript的内部对象
- android 动画坐标,android TranslateAnimation动画执行时的坐标获取。
- 知识付费海哥“”知识付费在贩卖焦虑,还是延缓焦虑