汇编语言 程序设计
第 9章 输入 /输出程序设计
◆ 输入 /输出指令
◆ 输入/输出控制方式
◆ 中断
◆ BIOS中断调用
汇编语言 程序设计
9.1 输入 /输出指令
9.1.1 I/ O端口寻址
当设备通过接口与主机相连时, CPU可以通过接口地址
来访问 I/O设备 。 通常将 I/O设备码视为地址码, 对 I/O地址
码的编址可采用存储器编址和 I/O端口编址两种方式 。
1,存储器编址方法
存储器编址也叫统一编址, 就是将 I/O地址看作是存储
器地址的一部分 。
2,I/O端口编址方法
I /O端口编址也称为不统一编址, 就是指 I/O地址和存
储器地址是分开的, 所有对 I/O的访问必须有专用的 I/O指令 。
汇编语言 程序设计
9.1.2 输入 /输出指令
1,输入指令
格式,IN OPERAND1,OPERAND2
其中:操作数 OPERAND1是 AL或 AX,操作数 OPERAND2是输入端口地址 。
输入指令 IN是把端口的一个字节或字传送给 AL或 AX。
2,输出指令
格式,OUT OPERAND1,OPERAND2
其中,OPERAND1是输出端口地址, OPERAND2是 AL或 AX,输出指令 OUT把 AL或 AX中的内容输出到端口 。
3,端口地址的寻址方式
用上两条指令时, 有直接和间接两种寻址方式来确定端口地址 。
(1) 直接端口寻址
输入 /输出指令的端口地址可以是直接给出, 此时指令为双字节,第二字节即为一个具体的 8位二进制数, 可对 0-255个 8位端口寻 。
(2) 间接端口寻址
间接端口寻址是采用寄存器 DX的内容来指定端口地址, 此寻址方式的指令是单字节指令 。 因为 DX是 16位寄存器, 所以这种寻址方式可
对 0-65535个 16位端口进行寻址 。 当端口号大于 255时, 就应采用间接端口寻址 。
返回
汇编语言 程序设计
9.2 输入/输出控制方式
9.2.1 程序控制方式
程序控制方式是在用户程序的控制下实现主机 ( CPU) 与外设交
换信息, 对哪个端口何时进行输入 /输出操作, 都在程序中反映出来 。
具体实现时又有立即传送和程序查询两种方法 。
1,立即传送方 式
采用这种方法时, 应该确定外设已经准备好, 因此不再询问外设
是否准备情况, 在程序中需要输入 /输出时, 就向指定端口进行输入
/输出操作 。
2,程序查询方式
若 CPU与外设交换信息时, 根据外设的工作状态来决定是否进行
交换, 这就是程序查询方法, 这时 CPU常常要查询外设的某些标记,
然后再作出决定, 就是程序查询方式 。
汇编语言 程序设计
9.2.2 中断控制方式
程序控制方式的立即传送方法, 不能根据设备实时状
况操作, 而程序查询方式使这种问题得以解决, 但工作时
CPU与外设相当串联工作, 占用 CPU大量时间, 因此工作效
率不可恭维 。 如果在外设已准备好的情况下, 通知 CPU,这
时 CPU才停下原来的工作与外设实施数据交换, 此次信息交
换完成后 CPU在继续自己的原有工作, 按此想法就产生了中
断工作方式 。
CPU启动外设后仍继续执行原程序, 在第 K条指令执行结
束后, CPU响应了外设的请求, 中断了现行程序, 转至中断
服务程序, 等处理完后又返回到原程序断点处, 继续从第
K+1条指令往下执行 。 这种方式中断了原程序的运行, 所以
称为程序中断方式 。
汇编语言 程序设计
9.2.3 直接存储器存取方式
如果外设能直接与主存交换信息而不占用 CPU,CPU的资源利用率
显 然 又 可 进 一 步 提 高, 这 就 出 现 了 直 接 存 储 器 存 取 的
DMA(DirectMemoryAccess)方式 。
DMA的数据块传送操作可以分为 3个主要步骤:
(1)预处理阶段:由 CPU执行几条输入输出指令, 测试设备状态;
向 DMA控制器的设备地址寄存器中送入设备号, 并启动设备;向内存地
址计数器送入起始地址;向字计数器中送入交换的数据字的个数 。
(2)正式传送阶段:外设准备好发送数据 (输入 )或接收数据 (输出 )
时, 发出 DMA请求, 由 DMA控制器向 CPU发出总线使用权的请求 ; CPU在
本机器周期执行完毕后响应该请求并使 CPU的总线驱动器处于高阻状态,
然后与系统总线相脱离, DMA控制器接管数据总线和地址总线的控制,
并向内存提供地址;在内存与外围设备之间进行数据交换, 每交换一
个字则地址计数器和字计数器减 1,当计数值到 0时, DMA操作结束并向
CPU提出中断申请 。
(3)DMA后处理工作:一旦 DMA的中断请求得到响应, CPU将停止主
程序的执行, 转去执行中断服务程序进行 DMA操作的后处理 。 包括校验
送入内存的数据是否正确;决定使用 DMA方式传送数据还是结束传送;测试传送过程中是否发生错误 。
返回
汇编语言 程序设计
9.3 中断
9.3.1 中断概念
1.中断概念
计算机在执行程序的过程中,在出现异常情况或特殊请求时,计
算机停止现行运行程序,转向对这些异常情况或特殊请求的处理,
处理结束后再返回到现行程序的间断处,称之为计算机上的, 中
断, 。
2.中断的应用场合
(1) 及时处理计算机中的紧急事件
突发故障在用户程序中是无法反映的, 但它的出现可导致运行结果
出错, 甚至出现意想不到的后果, 为了及时处理这些故障, 应该采
用中断方式 。
(2) 协调主机与外设工作速度
大部分外设的工作速度均低于 CPU,采用程序查询方式, 会占用
了 CPU的宝贵时间 。 采用中断控制方式, 可以很好的解决这一问题 。
(3) 实时控制
汇编语言 程序设计
9.3.2 中断源、中断类型码和中断优先级
1.中断源
引起中断的原因或来源称为中断源( Interrupt source)。
( 1) 外部中断
不是因为 CPU内部原因产生的中断, 称为外部中断 。 而外部中
断又分为非屏蔽中断 NMI和可屏蔽中断 INTR两种 。
( 2) 内部中断
由 CPU内部产生的中断, 称为内部中断 。 按引发情况可分为 3
类 。 例如除法运算出错, 执行软中断指令, 单步中断等 。
2,中断类型码
PC机为每一个中断源分配一个号码, 称为中断类型码 。 这些
中断类型码在 PC机中是唯一的, 有的是系统统一规定的, 有的是
由用户指定中断类型码 。
汇编语言 程序设计
3,中断优先级
在某时如只有一个中断源提出中断请求,
若它是非屏蔽中断源,那么 CPU就会立即响应
它的请求;若它是可屏蔽中断源,只要 IF=1,
CPU也会立即响应它的请求。但是,如果在同
一时刻有几个中断源同时提出中断请求,CPU
只能先响应 1个中断源,如果 CPU响应了一个中
断源的中断请求后,在执行中断处理程序的时
候,又有一个中断源提出中断请求,CPU能否
响应这个新的中断请求,这就引出了中断优先
级问题。
汇编语言 程序设计
9.3.3 中断矢量表
不同的中断来自不同的中断源, 因此有着不同的处理任务, PC机
有 256个不同的中断, 对每一个中断源都要设计一个中断处理程序, 而
且每一个中断程序都有自己的入口地址, 将 256个中断程序的入口地址
放到一起, 就形成了一个表, 称之为中断矢量表 。 PC机的中断矢量表
是在在内存最小地址的 1k字节 ( 绝对地址为,00000H~003FFH) 空间建
立的, 由此表确定了中断类型码与该中断源所对应的中断处理程序之
间的一一对应联系 。 图 9.12给出中断矢量表的安排, 表内存放有 256个
中断处理程序入口地址 。 每个入口地址由 4个字节组成, 两个低字节存
放入口地址的偏移量, 两个高字节存放它的段基值 。 中断响应以后,
表中对应的 4个字节的内容分别被送人 IP和 CS,完成程序转移 。 表中中
断类型 0,类型 1,类型 2等表示这个入口地址对应的中断类型码 。 如果
已知现在响应中断的中断类型码, 就可以从中断矢量表中找到该中断
源的处理程序入口地址 。 设中断类型码为 N,则有:
中断矢量地址 =中断类型号 *N
也就是 ( 4*N,4*N十 1) → IP; (4*N+2,4*N十 3) → CS
这样就把中断处理程序的入口地址的偏移量和段基值分别送人 IP
和 CS,然后到此地址执行该中断的服务子程序 。
汇编语言 程序设计
9.3.4 中断过程
一个完整的中断过程,要先后经历中断请求、中断响应、中断
处理及中断返回等 4步骤。
1,中断请求
这是引起中断的第 1步。中断源产生中断请求的条件,对不同的
中断源是不一样的。
2,中断响应
CPU在每执行一条指令的后期,都要查询是否有中断请求。若有,
就按照优先顺序给予响应或不响应。查询中断请求按优先级从高到
低的顺序进行。如果 CPU响应,就识别并读出得到响应的中断源的类
型码。
3.中断处理
由于每个中断处理的任务不同,因此具体中断处理不可能一样,
但是也存在一些共性。,简单的说中断处理一般可由四个部分组成,
即:现场保护、具体中断处理、现场恢复以及中断返回指令。
4.中断返回
每一个中断处理子程序的最后要使用中断返回指令 IRET以退出
中断,返回原断点处。该指令是无操作数指令,其功能是:首先从
堆栈中弹出中断断点地址,分别送人 IP和 CS,然后恢复标志寄存器
内容。
汇编语言 程序设计
9.3.5 软中断及有关的中断指令
软中断属于内部中断,软中断( Soft Interruptions) 指令的格
式为:
INT n
其中 n为中断类型号。
PC机的软中断分为 BIOS中断,DOS中断和自由中断三部分。
1,BIOS 中断( 10H-1FH)
固化在 ROM中,称为 ROM BIOS,常用中断有:
INT 10H-屏幕显示
INT 13H-磁盘读写
INT 16H -键盘输入
2,DOS中断( 20H-3FH)
其中 22H,23H,24H号是 DOS专用中断,21H,20H,25H,26H、
27H,2FH 为用户可调用中断。
3,自由中断( 40H-FFH)
自由中断主要供系统和用户应用程序扩充使用。 返回
汇编语言 程序设计
9.4 BIOS中断调用
BIOS是 Basic Input/Output System的缩写, 是固化在 PC机
ROM中的基本输入输出系统, 它提供系统加电自检, 引导装入,
主要 I/O设备的处理程序以及接口控制等功能模块, 一般以中断
处理程序的形式存在 。 BIOS可以处理所有的系统中断, 如键盘,
显示器, 磁盘, 打印, 日期与时间等 。 BIOS是模块化的结构形式,
每个功能模块的入口地址都在中断矢量表中 。 在 1k中断矢量表中,
共有 256个中断调用的入口地址 。 对这些中断调用是通过软中断
指令 INT来实现的, 软中断指令的操作数就是中断类型码 。
使用 BIOS功能调用,给程序员编程带来很大的方便,程序员
不必了解硬件 I/O接口的特性,可直接用指令设置参数,然后中
断调用 BIOS中的程序,所以利用 BIOS功能编写的程序可读性好,
易于移植。有时为了提高处理效率,应用程序也可以通过输入输
出指令直接操纵外设接口控制外设,但这种情况下程序员要熟悉
相关的硬件特性,而且应用程序的设计比较复杂,这是 BIOS不方
便之处。
汇编语言 程序设计
9.4.1 键盘输入中断调用
键盘中断调用( 1NT 16H) 现有 9个子功能,其中 0、
1和 2号功能较常用。键盘调用 01H-03H子功能见下表。
功能号 输入 输出 功能
01H AH=00H
AH=键盘扫描代码 AL=
字符的 ASCII码 读键盘键入的一个 ASCII字符
02H AH=01H
AH=键盘扫描码 AL=字
符的 ASCII码若有键
按下 ZF=0,
否则 ZF=1
读键盘状态并检查键盘是否有字符输入
02H AH=02H AH=00HAL=键盘标志字 读键盘标志字
D7 D6 D5 D4 D3 D2 D1 D0
Insert CapsLock NurnLock ScrollLock Alt键 Ctrl键 Left-Shift Right-Shift
激活为 1 激活为 1 激活为 1 激活为 1 按下为 1 按下为 1 按下为 1 按下为 1
在 AL中各状态位意义如下
汇编语言 程序设计
显示器输出控制中断调用的中断类型号为 10H,总共有 00H-1CH的子调用, 通过这些子功能子程序的调用, 可以在屏幕指定位置上
以字符方式或图形方式显示 。
在子程序的调用中 00H,02H,03H,05H,06H,07H,08H,09H、0AH,0CH,0DH和 0CH是基本的调用。
1,视频模式
00H号子调用是指定视频模式, PC机显卡有文本和图形两种显示模式 。
文本显示方式, 是指以字符为单位显示的方式, 字符通常是指字母, 数字, 普通符号和一些特殊符号 ( 如矩形块等 ) 。 在这种显
示方式下, 显示缓冲存储区中存放的是字符的 ASCII码和对应的显示属性, 每个字符占用两个字节的空间 。 文本模式可以显示 256种
不同字符, 如在 3号文本显示模式下, 显示器的屏幕被划分成 80列25行, 因此一屏最多可以显示 80x25( 2000) 个字符 。
图形显示方式中, 显示缓冲存储区中存放的是, 像素, 点的信息, 每个像素对应屏幕上的一点位置, 它的值为, 0” 或者, 1”,
为, 0” 就不在屏幕上打点, 为, 1” 则在屏幕上打点 。
9.4.2 显示器输出控制中断调用
汇编语言 程序设计
2,字符的属性
字符的显示属性是字符显示时的特性,用一个描述颜色的字节信息来规定。文本方式的显示属性字节,字符单色文本显示和彩色
文本显示的属性字节略有区别,对于单色显示,位 6,5,4或位 2、1,0三位全为 0是表示黑色,全是 1时表示黑色白色,对于彩色显示
是由 RGB这 3位颜色组合给出的颜色。其中 BL为 0表示前景字符不闪烁,为 1表示前景字符闪烁; I为 0表示前景字符为一般强度,为 1表
示前景字符为高强度。单色文本方式的显示属性字节取值和采色( 16色)文本方式的颜色组合请看书中表。
3.调用格式
各子功能调用格式为:
MOV AH,功能号
┇ ;其他调用参数
INT 10H ; 功能调用
其他调用参数的一般规则是:
要显示的字符或像素值通常在 AL中;
X坐标 (列号 ):图形方式在 CX中, 字符方式在 DL中;
Y坐标 (行号 ):图形方式在 DX中, 字符方式在 DH中;
显示的页号在 BH中 。
汇编语言 程序设计
9.4.3 时间中断调用
INT 1AH称为系统定时器和实时时钟( RTC) 服务,包括 11个子功能调用,其中常用的是 00和 01号子功能,下面主要介绍这两个功能
调用。 1.读取时间计数器当前值( 00H)
调用前,AH=00H
子功能调用返回时:
CX=时间计数器的高位字
DX时间计数器的低位字
AL=0,未计满 24小时
AL=1,已计满 24小时
时间计数器约 54.926ins计数一次, 所以可按下列公式计算出当前的时间:
时:时间计数器的值 (CX:DX)/ 65543; 时的余数 =时间计数器的值 MOD 65543
分:时的余数 /1092;分的余数 =时的余数 MOD 1092
秒:分的余数/ 18,21
2,设置时间计数器的当前值 ( 01H)
子功能调用前,AH=01H
CX=时间计数器当前值高位字
DX=时间计数器当前值低位字
按下列公式计算出当前时间值:
CX:DX=(时 *65543)十 (分 *1092)十 (秒 *18.21)
返回
汇编语言 程序设计
9.4.4 中断调用程序举例
1,键盘
【 例 9.5】 将用户按的键盘显示出来, 当按下 FHIFT键后结束运行, 请编写程序 。
SHIFT_L=02H;
SHIFT_R=01H
STACK SEGMENT STACK
DB 200 DUP(0)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,SS:STACK
BEGIN,MOV AH,02H ;取键盘状态字节
INT 16H
TEST AL,SHIFT_L+SHIFT_R ;判断是否按下 SHIFT键
JNZ EXIT ;按下, 结束程序
MOV AH,01H ;判断是否有键可读
INT 16H
JZ BEGIN ;没有, 转去继续读键
MOV AH,00H ;读键
INT 16H
MOV DL,AL ;显示所读键
MOV AH,02H
INT 21H
JMP BEGIN ;继续读键
EXIT,MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN
汇编语言 程序设计
9.4.4 中断调用程序举例
2,显示输出
【 例 9.6】 在字符显示方式下显示 'College ofComputer Science & Technology,BeiHua
University'。
STACK SEGMENT PARASTACK
DB 60 DUP (0)
STACK ENDS
DATA SEGMENT
CHAR DB 'College ofComputer Science & Technology,BeiHua University'
COL DB 0 ;开始的列号
ROW DB 10 ;开始的行号
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START,MOV AX,DATA
MOV DS,AX
MOV AH,0
MOV AL,03H ;置字符显示方式
INT 10H ;置 640x 200图形方式
LOP1,LEA BX,CHAR
PUSH BX
MOV DL,COL
MOV CX,58
汇编语言 程序设计
LOP2,MOV AH,2
MOV DH,ROW
INC DL
INT 10H
POP BX
MOV AL,[BX]
INC BX
PUSH BX
PUSH CX
MOV AH,0AH
MOV BH,0
MOV CX,1
INT 10H
POP CX
LOOP LOP2
POP BX
QUIT,MOV AH,4CH
INT 21H
CODE ENDS
END START
汇编语言 程序设计
【 例 9.8】 每隔 5.5S从键盘读一个字符并将其 ASCII码送入内存缓冲区, 共 200个字符 。
CHAR DB 200 DUP(?)
STR,MOV CX,200
LEA BX,CHAR
STI
LOP_1,MOV AH,1
PUSH CX
MOV CX,0
MOV DX,0
INT 1AH ;时间中断调用
LOP_2,MOV AH,0
INT 1AH
CMP DL,200
JNZ LOP_2
MOV AH,0
INT 16H
MOV [BX],AL
INC BX
POP CX
LOOP LOP_1
HLT ;停止程序
3.时间中断应用