【汇编语言】中断及外部设备操作
文章目录
- 【汇编语言】中断及外部设备操作
- 前言
- 一、中断及其处理
- 中断的概念
- 8086内中断
- 中断处理程序
- 案例:系统中的0号中断
- 中断过程
- 二、编制中断处理程序
- 中断处理程序及其结构
- 编制中断处理程序——以除法错误中断为例
- do0子程序应该放在哪里?
- 程序框架
- do0安装程序的实现
- do0子程序的实现
- 小结
- 三、单步中断
- 由Debug中的t命令说起
- 单步中断过程与处理
- 应用:中断不响应的情况
- 四、由int指令引发的中断
- int n引起的中断
- 编写供应用程序调用的中断例程
- 示例 :中断7ch的中断例程(1)
- 示例 :中断7ch的中断例程(2)
- 五、BIOS和DOS中断处理
- BIOS——基本输入输出系统
- BIOS中断调用示例
- 有哪些BIOS中断,怎么用?
- 汇编的强大功能,还有DOS中断!
- int 21H DOS 中断例程的应用
- BIOS和DOS中断例程的安装过程
- 六、端口的读写
- 用端口访问外设:以发声为例
- CPU的邻居
- 端口的读写
- I/O端口分配
- 端口的读写指令示例
- 七、操作CMOS RAM 芯片
- 端口操作示例:提取CMOS RAM中存储的时间信息
- 在屏幕中间显示当前的月份
- 八、外设的连接与中断
- CPU通过端口与外部设备“连接”
- 外中断:由外部设备发生的事件引起的中断
- 外中断处理过程
- 九、PC机键盘的处理过程
- PC机键盘的处理过程
- 键盘上键的扫描码(通码)
- PC机键盘的处理过程——引发中断
- PC机键盘的处理过程——执行中断例程
- 输入‘a’
- 十、定制键盘输入处理
- PC机键盘的处理过程(int 9 中断例程)
- 实现:依次显示'a'~'z'(v0.2)
- 实现:依次显示”a”~”z”(v0.4)
- 按下 Esc 键后改变显示的颜色
- 实现: 按下 Esc 键后改变显示的颜色(v1.0)
- 十一、改写中断例程的方法
- 改写中断例程-以int 9为例
- 实现方法
- 十二、用中断响应外设
- 如何操作外部设备?
- 键盘输入的处理的int 9h中断和int 16h中断
- 调用int 16h 从键盘缓冲区中读取键盘的输入
- 十三、应用:字符串的输入
- 要解决的问题
- 程序的处理过程
- 子程序:字符栈的入栈、出栈和显示
- 实现字符栈的入栈、出栈和显示
- 十四、读写磁盘
- BIOS提供的磁盘直接服务——int 13h
- 用BIOS int 13h对磁盘进行读操作
- 用BIOS int 13h对磁盘进行写操作
- DOS中断对磁盘文件的支持——int 21H
- 十五、让计算机“唱歌”
- 外部设备与如何被控制的?
- 与"计算机唱歌"有关的硬件及控制
- 翻译乐谱
- 演奏程序
- 总结
前言
本篇文章我们会详细讲到,中断及其处理,编制中断处理程序,单步中断,有int指令引发的中断,BIOS和DOS中断处理。端口的读写,操作CMOS RAM芯片,外设连接与中断,PC机键盘的处理过程,定制键盘输入处理,改写中断历程的方法,用中断相应外设,应用:字符串的输入,磁盘读写,发声程序。
一、中断及其处理
中断的概念
中断:CPU不再接着(刚执行完的指令)向下执行,而是转去处理中断信息。
内中断:由CPU内部发生的事件而引起的中断。
外中断:由外部设备发生的事件引起的中断。
8086内中断
CPU内部产生的中断信息
除法错误,比如:执行div指令产生的除法溢出
单步执行
执行into指令
执行int 指令8086的中断类型码:
1)除法错误:0
2)单步执行:1
3)执行 into 指令:4
4)执行 int n指令 ,立即数 n 为中断类型码。
中断处理程序
CPU接到中断信息怎么办?
执行中断处理程序。
中断处理程序在哪里?
中断信息和其处理程序的入口地址之间有某种联系,CPU根据中断信息可以找到要执行的处理程序。
中断向量表:
由中断类型码,查表得到中断处理程序的入口地址,从而定位中断处理程序。
8086CPU的中断向量表:
案例:系统中的0号中断
中断过程
中断过程: 中断过程由CPU的硬件自动完成; 用中断类型码找到中断向量,并用它设置CS和IP 8086CPU的中断过程:
1)从中断信息中取得中断类型码
2)标志寄存器的值入栈——中断过程中要改变标志寄存器的值,需要先行保护
3)设置标志寄存器的第8位TF 和第9位IF的值为0
4)CS的内容入栈;
5)IP的内容入栈;
6)从中断向量表读取中断处理程序的入口地址,设置IP和CS。
二、编制中断处理程序
中断处理程序及其结构
CPU随时都可能检测到中断信息,所以中断处理程序必须常驻内存(一直存储在内存某段空间之中)。
中断处理程序的入口地址,即中断向量,必须存储在对应的中断向量表表项中(0000:0000-0000:03FF)。
编制中断处理程序——以除法错误中断为例
问题:如何编制中断处理程序?
方案:通过对 0号中断,即除法错误的中断处理,体会中断处理程序处理的技术问题。
预期效果:编写一个0号中断处理程序,它的功能是在屏幕中间显示“overflow!”后,然后返回到操作系统。
第1个问题:do0子程序应该放在哪里?
do0子程序应该放在哪里?
程序框架
1)编写可以显示“overflow!”的中断处理程序:do0;
2)安装程序:将do0送入内存0000:0200处;
3)将do0中断处理程序的入口地址0000:0200存储在中断向量表0号表项中。
第2个问题:怎么写安装程序?
do0安装程序的实现
第3个问题:do0怎么写?
第4个问题:设置中断向量表
do0子程序的实现
小结
三、单步中断
由Debug中的t命令说起
程序的正常执行:取指令、改变CS:IP、执行指令、取指令…
Debug提供了单步中断的中断处理程序,功能为显示所有寄存器中的内容后等待输入命令。
是什么,让CPU能执行一条指令就停下来?
Debug利用了CPU提供的单步中断的功能
使用t命令时,Debug将TF标志设为1,使CPU工作在单步中断方式下…
自定义单步中断处理程序,还可以实现特殊的功能。
单步中断过程与处理
两个和中断相关的寄存器标志位:
TF-陷阱标志(Trap flag):用于调试时的单步方式操作。当TF=1时,每条指令执行完后产生陷
阱,由系统控制计算机;当TF=0时,CPU正常工作,不产生陷阱。
IF-中断标志(Interrupt flag):当IF=1时,允许CPU响应可屏蔽中断请求;当IF=0时,关闭中断。
应用:中断不响应的情况
一般情况下,CPU在执行完当前指令后,如果检测到中断信息,就响应中断,引发中断过程。
在有些情况下,CPU 在执行完当前指令后,即便是发生中断,也不会响应。
例:在执行完向 ss寄存器传送数据的指令后,即便是发生中断,CPU 也不会响应。
原因:ss:sp联合指向栈顶,而对它们的设置应该连续完成。
以此保证对栈的正确操作!
四、由int指令引发的中断
int n引起的中断
CPU内部产生的中断信息
除法错误
单步执行
执行into指令
执行int 指令
int格式: int n,n为中断类型码
功能:引发中断过程
CPU 执行int n指令,相当于引发一个n号中断过程,执行过程如下:
1)取中断类型码n;
2)标志寄存器入栈,IF = 0,TF = 0;
3)CS、IP入栈;
4)(IP) = (n4),(CS) = (n4+2)。—从此处转去执行n号中断的中断处理程序。
编写供应用程序调用的中断例程
技术手段:编程时,可以用 int指令调用子程序
此子程序即中断处理程序,简称为中断例程
可以自定义中断例程,实现特定功能
示例:中断7ch的中断例程的编写和安装
中断例程序需要按中断的运行机制的要求编写
参考:中断0 的中断例程
示例 :中断7ch的中断例程(1)
任务:编写程序
写7ch的中断例程,完成特定任务
功能:求一个word型数据的平方
参数: (ax)=要计算的数据
返回值:dx, ax中存放结果的高、低16位
编写安装中断例程
测试
应用举例:求2*3456^2
对中断例程的要求
示例 :中断7ch的中断例程(2)
7ch的中断例程的任务
功能:将以 0结尾的字符串转化为大写。
参数: ds:si指向字符串的首地址
五、BIOS和DOS中断处理
BIOS——基本输入输出系统
BIOS中断调用示例
任务:在屏幕的5行12列显示3个红底高亮闪烁绿色的’a’
回顾:
显示缓冲区结构
用BIOS的10h中断:
(ah)=2时,调用第10h中断例程的2号子程序,设置光标位置
(ah)=9时,调用第10h中断例程的9号子程序,在光标位置显示字符
有哪些BIOS中断,怎么用?
汇编的强大功能,还有DOS中断!
int 21H DOS 中断例程的应用
4ch号功能:程序返回
功能号在ah,返回结果保存在al
用法: mov ah,4ch
mov al,0
int 21h
或者:
mov ax,4c00h
int 21h
09h号功能:在光标位置显示字符串:
ds:dx指向要显示的字符串(用’$'结束)
用法:
mov ah ,9
int 21h
例:
编程在屏幕的5行12列显示字符串
“welcome to masm!”。
BIOS和DOS中断例程的安装过程
1)CPU 一加电,初始化(CS)=0FFFFH,(IP)=0,自动从FFFF:0单元开始执行程序。FFFF:0处有一条转跳指令,CPU执行该指令后,转去执行BIOS中的硬件系统检测和初始化程序。
2)初始化程序将建立BIOS 所支持的中断向量,即将BIOS提供的中断例程的入口地址登记在中断向量表中。
3) 硬件系统检测和初始化完成后,调用int19h进行操作系统的引导。从此将计算机交由操作系统控制。
4)DOS 启动后,除完成其它工作外,还将它所提供的中断例程装入内存,并建立相应的中断向量。
六、端口的读写
用端口访问外设:以发声为例
CPU的邻居
CPU可以直接读写3 个地方的数据
1)CPU 内部的寄存器
2)内存单元
3)端口:对应各种接口卡,网卡、显卡等;主板上的接口芯片;其他芯片;
读写内存与寄存器的指令
mov, add, push…
读写端口的指令
in: CPU从端口读取数据
out: CPU往端口写入数据
端口的读写
访问端口的方法:
例: in al, 60h ; 从60h号端口读入一个字节
执行时与总线相关的操作
① CPU通过地址线将地址信息60h发出;
② CPU通过控制线发出端口读命令,选中端口所在的芯片,并通知要从中读取数据;
③ 端口所在的芯片将60h端口中的数据通过数据总线送入CPU。
I/O端口分配
端口的读写指令示例
对0~255以内的端口进行读写,端口号用立即数给出
in al,20h ;从20h端口读入一个字节
out 21h,al ;往21h端口写入一个字节
对256~65535的端口进行读写时,端口号放在dx中
mov dx,3f8h ;将端口号3f8送入dx
in al,dx ;从3f8h端口读入一个字节
out dx,al ;向3f8h端口写入一个字节
注意:在in和out 指令中,只能使用ax 或al 来存放从端口中读入的数据或要发送到端口中的数据。访问8 位端口时用 al ,访问16 位端口时用ax 。
七、操作CMOS RAM 芯片
CMOS RAM 芯片
1)包含一个实时钟和一个有128个存储单元的RAM存储器。
2)128 个字节的 RAM 中存储:内部实时钟、系统配置信息、相关的程序(用于开机时配置系统信息)。
3) CMOS RAM 芯片靠电池供电,关机后其内部的实时钟仍可正常工作, RAM 中的信息不丢失。
4)该芯片内部有两个端口,端口地址为70h和71h,CPU 通过这两个端口读写CMOS RAM。
; 70h地址端口,存放要访问的CMOS RAM单元的地址。
; 71h数据端口,存放从选定的单元中读取的数据,或要写入到其中的数据。
端口操作示例:提取CMOS RAM中存储的时间信息
问题描述
在屏幕中间显示当前的月份
事实
在CMOS RAM中的时间信息含有月份
背景知识
分析:这个程序主要做两部分工作
1)从CMOS RAM的8号单元读出当前月份的BCD码
2)将用BCD码表示的月份以十进制的形式显示到屏幕上。
在屏幕中间显示当前的月份
1)从CMOS RAM的8号单元读出当前月份的BCD码
首先要向地址端口70h写入要访问的单元的地址-月份8
mov al,8
out 70h,al
再从数据端口71h中取得指定单元中的数据-月份值
in al,71h
2)将用BCD码表示的月份以十进制的形式显示到屏幕上
将读到的数据前4位和后4位分离出来
由低4位为BCD码的“数字”转为ASCII码
由:BCD 码值=十进制数码值
得:十进制数对应的ASCII码 = BCD码值+30h
显示
八、外设的连接与中断
CPU通过端口与外部设备“连接”
外中断:由外部设备发生的事件引起的中断
可屏蔽中断:
可屏蔽中断是CPU 可以不响应的外中断。
CPU 是否响应可屏蔽中断,要看标志寄存器的IF 位的设置。
当CPU 检测到可屏蔽中断信息时:
如果IF=1,则CPU 在执行完当前指令后响应中断,引发中断过程;
如果IF=0,则不响应可屏蔽中断。
不可屏蔽中断:
不可屏蔽中断是CPU 必须响应的外中断;
当CPU 检测到不可屏蔽中断信息时,则在执行完当前指令后,立即响应,引发中断过程。
对于8086CPU 不可屏蔽中断的中断类型码固定为2。
外中断处理过程
可屏蔽中断所引发的中断过程:
1)取中断类型码n;
2)标志寄存器入栈,IF=0,TF=0;
3)CS 、IP 入栈;
4)(IP)=(n4),(CS)=(n4+2)
由此转去执行中断处理程序
不可屏蔽中断的中断过程:1)标志寄存器入栈,IF=0,TF=0;
2)CS、IP入栈;
3)(IP)=(8),(CS)=(0AH)。
九、PC机键盘的处理过程
PC机键盘的处理过程
键盘输入的处理过程
1、键盘输入
2、引发9号中断
3、执行int 9中断例程
1、键盘输入:
键盘上键的扫描码(通码)
PC机键盘的处理过程——引发中断
2、引发9号中断
输入的字符键值如何保存?
有BIOS键盘缓冲区!
BIOS键盘缓冲区:是系统启动后,BIOS用于存放int 9 中断例程所接收的键盘输入的内存区。
BIOS键盘缓冲区:可以存储15 个键盘输入,一个键盘输入用一个字单元存放,高位字节存放扫描码,低位字节存放字符码。
输入了控制键和切换键,如何处理?
PC机键盘的处理过程——执行中断例程
3、执行int 9中断例程
输入‘a’
十、定制键盘输入处理
PC机键盘的处理过程(int 9 中断例程)
键盘输入的处理过程:
1)键盘产生扫描码;
2)扫描码送入60h 端口;
3)引发9 号中断; 前三由硬件系统完成的
4)CPU执行int 9中断例程,处理键盘输入; DOS系统提供int 9中断例程
按照开发需求定制处理键盘的输入
编程任务:
在屏幕中间依次显示 ‘a’~‘z’ ,并可以让人看清。
在显示的过程中,按下Esc键后,改变显示的颜色。
工作策略
尽可能忽略硬件处理细节,充分利用BIOS 提供的int 9中断例程对这些硬件细节进行处理。
在改写后的中断例程中满足特定要求,并能调用BIOS 的原int 9中断例程。
实现:依次显示’a’~‘z’(v0.2)
存在的问题:无法看清屏幕上的显示。
原因:同一位置显示字母,字母之间切换的太快,无法看清。
对策:在每显示一个字母后,延时一段时间
如何延时?让CPU执行一段时间的空循环。
实现:依次显示”a”~”z”(v0.4)
接下来的工作:按下 Esc键后,改变显示的颜色!
原理:键盘输入到达60h端口后,就会引发 9号中断,CPU 则转去执行int 9中断例程。
按下 Esc 键后改变显示的颜色
编写int 9中断例程改变显示的颜色
实现: 按下 Esc 键后改变显示的颜色(v1.0)
十一、改写中断例程的方法
改写中断例程-以int 9为例
任务:安装一个新的int 9中断例程
功能:在DOS下,按F1键后改变当前屏幕的显示颜色,其他的键照常处理。
要解决的问题
1)改变屏幕的显示颜色
改变从B800开始的4000个字节中的所有奇地址单元中的内容,当前屏幕的显示颜色即发生改变。
2)F1改变功能,其他键照常
可以调用原int 9中断处理程序,来处理其他的键盘输入
3)原int 9中断例程入口地址的保存
要保存原int 9中断例程的入口地址原因:在新int 9中断例程中要调用原int 9中断例程保存在哪里? 我们将地址保存在0:200单元处。
4)新int 9中断例程的安装
我们可将新的int 9中断例程安装在0:204 处。
实现方法
十二、用中断响应外设
如何操作外部设备?
以典型输入设计——键盘操作为例
键盘输入的处理的int 9h中断和int 16h中断
键盘缓冲区的实现
共16字;用环形队列;可存储15个按键扫描码
调用int 16h 从键盘缓冲区中读取键盘的输入
综前所述:int 16h 中断例程 0 号功能的实现过程
1)检测键盘缓冲区中是否有数据;
2)没有则继续做第1 步;
3)读取缓冲区第一个字单元中的键盘输入;
4)将读取的扫描码送入ah,ASCII 码送入al;
5)将己读取的键盘输入从缓冲区中删除。
事实
BIOS 的int 9 中断例程和int 16h 中断例程是一对相互配合的程序,int 9 中断例程向键盘缓冲区中写入,int 16h 中断例程从缓冲区中读出。
应用
我们在编写一般的处理键盘输入的程序的时候,根据需要用不同的方法。
应用示例:更改屏幕颜色
要求:接收用户的键盘输入
输入“r”,将屏幕上的字符设置为红色;
输入“g”, 将屏幕上的字符设置为绿色;
输入“b ”,将屏幕上的字符设置为蓝色。
十三、应用:字符串的输入
要解决的问题
问题:设计一个最基本的字符串输入程序,需要具备下面的功能
1) 在输入的同时需要显示这个字符串;
2)一般在输入回车符后,字符串输入结束;
3)能够删除已经输入的字符——用退格键。
讨论:
1)在输入的同时需要显示这个字符串
需要用栈的方式来管理字符串的存储空间
2)在输入回车符后,字符串输入结束
输入回车符后 ,在字符串中加入0,表示字符串结束。
3) 在输入的同时需要显示这个字符串
每次有新的字符输入和删除一个字符的时候,都应该重新显示字符串,即从字符栈的栈底到栈顶,显示所有的字符。
程序的处理过程
- 调用int 16h读取键盘输入;
- 如果不是字符:①如果是退格键,从字符栈中弹出一个字符,显示字符栈中的所有字符;继续执行(1) ;②如果是Enter 键,向字符栈中压入0,返回。
- 如果是字符键:字符入栈;显示字符栈中的所有字符;继续执行(1) ;
子程序:字符栈的入栈、出栈和显示
参数说明:
(ah)=功能号,0表示入栈,1表示出栈,2表示显示;
对于0 号功能:(al)=入栈字符
对于1 号功能:(al)=返回的字符;
对于2 号功能
(dh)、(dl) =字符串在屏幕上显示的行、列位置;
ds:si 指向字符串的存储空间,字符串以0为结尾符。
实现字符栈的入栈、出栈和显示
十四、读写磁盘
BIOS提供的磁盘直接服务——int 13h
用BIOS int 13h对磁盘进行读操作
入口参数:
(ah)=2(2表示读扇区)
(al)=读取的扇区数
(ch)=磁道号,(cl)=扇区号
(dh)=磁头号(对于软盘即面号,一个面用一个磁头来读写)
(dl)=驱动器号:软驱从0开始,0:软驱A,1:软驱B;硬盘从80h开始,80h:硬盘C,81h:硬盘D
es:bx指向接收从扇区读入数据的内存区
返回参数:
操作成功:(ah)=0,(al)=读入的扇区数
操作失败:(ah)=出错代码
例:读取C盘0面0道1扇区的内容到内存单元0:200;
用BIOS int 13h对磁盘进行写操作
入口参数:
(ah)=3(3表示写扇区)
(al)=写入的扇区数
(ch)=磁道号,(cl)=扇区号
(dh)=磁头号(对于软盘即面号)
(dl)=驱动器号:软驱从0开始,0:软驱A,1:软驱B;硬盘从80h开始,80h:硬盘C,81h:硬盘D
es:bx指向将写入磁盘的数据
返回参数:
操作成功:(ah)=0,(al)=写入的扇区数
操作失败:(ah)=出错代码
例:将0:200中的内容写入C盘0面0道1扇区
DOS中断对磁盘文件的支持——int 21H
十五、让计算机“唱歌”
外部设备与如何被控制的?
与"计算机唱歌"有关的硬件及控制
翻译乐谱
演奏程序
总结
到这里这篇文章的内容就结束了,谢谢大家的观看,如果有好的建议可以留言喔,谢谢大家啦!