1
第八章 输入输出程序设计
? I/O 设备的数据传送方式
? 程序直接控制 I/O 方式
? 中断传送方式
2
查询方式
( 程序控制方式 )
中断方式
DMA 方式
( 直接存储器存取方式 / 成组传送方式 )
1,I/O 设备的数据传送方式
3
I/O指令 是主机与外设进行通信的最基本途径 。
DOS功能调用和 BIOS例行程序中的输入 /输出功能
也是由 IN 和 OUT 指令完成的 。
例:循环测试某 状态寄存器 的第 2位是否为 1
AGAIN,IN AL,27H
TEST AL,00000100B
JZ AGAIN
2,程序直接控制 I/O 方式
4
设备控制寄存器 ( 61h )
1/0 0
控制其它外部设备

门 放大器
2号定时器门控
1 0
例,Sound 程序 1 ……
mov dx,100
in al,61h
and al,11111100b
sound,xor al,2
out 61h,al
mov cx,140h
wait1,loop wait1
dec dx
jne sound
……
5
.model tiny
.code
.startup
call speaker_on
mov ah,1
int 21h
call speaker_off
.exit 0
speaker_on proc
push ax
in al,61h
or al,3
out 61h,al
pop ax
ret
speaker_on endp
speaker_off proc
push ax
in al,61h
and al,0fch
out 61h,al
pop ax
ret
speaker_off endp
end
例,Sound 程序 2
6
……
call speaker_on
mov al,255
L1,out 42h,al
mov cx,500
L2,push cx
mov cx,0d000h
L2a,
loop L2a
pop cx
loop L2
sub al,1
jnz L1
call speaker_off
……
speaker_on proc
push ax
in al,61h
or al,3
out 61h,al
pop ax
ret
speaker_on endp
speaker_off proc
push ax
in al,61h
and al,0fch
out 61h,al
pop ax
ret
speaker_off endp
……
例,Sound 程序 3
7
print proc near
push ax
push dx
mov dx,378h ; 数据寄存器
out dx,al
mov dx,379h ; 状态寄存器
again,in al,dx
test al,80h
je again ; 打印机忙?
mov dx,37ah ; 控制寄存器
mov al,0dh
out dx,al ; 送选通信号
jmp $+2 ; 展宽选通信号
mov al,0ch
out dx,al
pop dx
pop ax
ret
print endp
例:打印机查询输出子程序
8
中断源,引起中断的事件
外中断 ( 硬中断 ),
外设的 I/O 请求 —— 可屏蔽中断
电源掉电 / 奇偶错 —— 非屏蔽中断
内中断 ( 软中断 ),
INT 指令 / CPU 错 (除法错, 溢出 ) / 为调试程序设置的中断
3,中断传送方式
9
非屏蔽中断请求
中断逻辑
INT n INTO 除法错 单步
n 4 0 1
CPU
2 NMI
8259A








( PIC )
IR0 系统定时器
IR1 键盘
IR2 彩色 /图形接口
IR3 保留
IR4 串行通讯口
IR5 保留
IR6 软盘
IR7 打印机
INTR
08
09
0A
0B
0C
0D
0E
0F
80x86 中断源,
10
设置 CPU中断允许位,
PSW 中的 IF 位 = 1 允许中断 ( STI )
= 0 禁止中断 ( CLI )
设置中断屏蔽位,
中断屏蔽寄存器的中断屏蔽位 = 0 允许中断
= 1 禁止中断
7 6 5 4 3 2 1 0








中断屏蔽寄存器 21H
7 6 5 4 3 2 1 0
中断命令寄存器 20H EOI
MOV AL,20H
OUT 20H,AL
8259A
CPU响应外设中断请求的条件,
11
类型 0 的 (IP)
类型 0 的 (CS)
类型 1 的 (IP)
类型 1 的 (CS)
类型 N 的 (IP)
类型 N 的 (CS)
类型 255的 (IP)
类型 255的 (CS)
00000
00004
4*N
003FC
中断向量
中断向量表
用户可利用保留的中断类型号
扩充自己需要的中断功能。
12
例:为中断类型 N 设置中断向量
……
MOV AX,0
MOV ES,AX
MOV BX,N*4
MOV AX,OFFSET INTHAND
MOV ES,WORD PTR[BX],AX ;偏移地址 ?(N*4)
MOV AX,SEG INTHAND
MOV ES,WORD PTR[BX+2],AX ;段地址 ?(N*4+2)
……
INTHAND,
…… ;中断处理程序
……
IRET
13
DOS 功能调用 ( 21H) 存取 中断向量,
设置中断向量,
AH = 25H
AL = 中断类型号
DS, DX = 中断向量
INT 21H
取中断向量,
AH = 35H
AL = 中断类型号
INT 21H
返回时送 ES, BX = 中断向量
14
MOV AL,N
MOV AH,35H
INT 21H ; 取原中断向量
PUSH ES
PUSH BX ; 保存原中断向量
PUSH DS
MOV AX,SEG INTHAND
MOV DS,AX
MOV DX,OFFSET INTHAND
MOV AL,N
MOV AH,25H
INT 21H ; 设置新的中断向量
POP DS
……
POP DX
POP DS
MOV AL,N
MOV AH,25H
INT 21H ; 恢复原中断向量
……
INTHAND,
……
IRET
例:用 DOS 功能调用存取中断向量
15
中断程序的编写步骤,
主程序,
(1) 设置中断向量
(2) 设置 CPU 的中断允许位 IF
(3) 设置设备的中断屏蔽位
中断处理子程序,
(1) 保存寄存器内容
(2) 如允许中断嵌套, 则开中断
(3) 处理中断
(4) 关中断
(5) 送中断结束命令 ( EOI )给中断命令寄存器
(6) 恢复寄存器内容
(7) IRET中断返回
16
例:编写一个中断处理程序,要求在主程序运行期间,
每隔 10 秒响铃一次,并显示 ‘ bell’
mov al,1ch
mov ah,35h
int 21h
push es
push bx
push ds
mov dx,offset ring
mov ax,seg ring
mov ds,ax
mov al,1ch
mov ah,25h
int 21h
pop ds
in al,21h
and al,11111110b
out 21h,al
sti
,model small
,stack
,data
cnt dw 1
mes db 'bell',0ah,0dh,'$'
,code
main proc far
start,
mov ax,@data
mov ds,ax
17
mov di,30000
dly,mov si,60000
dly1,
dec si
jnz dly1
dec di
jnz dly ;主程序
pop dx
pop ds
mov al,1ch
mov ah,25h
int 21h
mov ax,4c00h
int 21h
main endp
ring proc near
…… ;保存寄存器
mov ax,@data
mov ds,ax
sti ;开中断
dec cnt
jnz exit
mov dx,offset mes
mov ah,09
int 21h
call sound
mov cnt,182
exit,cli ;关中断
…… ;恢复寄存器
iret
ring endp
end start
18
例:键盘模拟程序
字符码,采用 ASCII 码表示字母、数字、专用字符和一些
非打印字符,键盘上的控制键和功能键的 ASCII
码为 0,必须用扫描码来识别。
扫描码,键盘上的每个键都对应一个扫描码,扫描码是按
键的位置来排列的。
data segment
scatab db 0,0,'1234567890-=',8,0
db 'qwertyuiop[]',0dh,0
db 'asdfghjkl;',0,0,0,0
db 'zxcvbnm,./',0,0,0
db ' ',0,0,0,0,0,0,0,0,0,0,0,0,0
db '789-456+1230',0
data ends
19
键 盘 缓 冲 区 的 例 子
20
main proc far
……
lea bx,scatab
key_in,
in al,60h
test al,80h
jnz key_in
push ax
in al,61h
or al,80h
out 61h,al
and al,7fh
out 61h,al
pop ax
cmp al,01
jz exit ;按 Esc退出
xlatb
cmp al,0
jz no_disp
call disp_char
no_disp,
jmp key_in
exit,……
main endp
disp_char proc near
mov ah,2
mov dl,al
int 21h
ret
disp_char endp
7 6 5 4 3 2 1 0
设备控制寄存器 61H
键盘
21
例:从键盘接收字符,同时对 32字节的输入缓冲区进行测试;
如缓冲区已满,将键盘挂起,由打印机输出一个提示信息
程序包括以下几个部分,
main 初始化部分
kbint 键盘中断处理程序
intip 初始化打印机
prtint 打印机中断处理程序
disp 用十六进制显示 al中的内容
22
dseg segment
addr dw? ;缓冲区指针
count dw?
buffer db 20h dup (' ')
prompt db 'please input:',0dh,0ah,'$'
message db 'buffer overflow',0dh,0ah
save_ip9 dw?
save_cs9 dw?
save_ipf dw?
save_csf dw?
dseg ends
main proc far
……
mov addr,offset buffer
mov count,0
23
mov al,09 ;键盘
mov ah,35h
int 21h
mov save_ip9,bx
mov save_cs9,es
mov dx,offset kbint
push ds
mov ax,seg kbint
mov ds,ax
mov al,09
mov ah,25h
int 21h
pop ds
in al,21h
and al,0fdh
out 21h,al
mov al,0fh ;打印机
mov ah,35h
int 21h
mov save_ipf,bx
mov save_csf,es
mov dx,offset prtint
push ds
mov ax,seg prtint
mov ds,ax
mov al,0fh
mov ah,25h
int 21h
pop ds
mov ah,9
lea dx,prompt
int 21h
24
sti
mov di,8000h
dly,mov si,9000h
dly1,
dec si
jnz dly1
dec di
jnz dly
mov ah,2
mov dl,'$'
int 21h
cli
push ds
mov dx,save_ip9
mov ax,save_cs9
mov ds,ax
mov al,09
mov ah,25h
int 21h
pop ds
push ds
mov dx,save_ipf
mov ax,save_csf
mov ds,ax
mov al,0fh
mov ah,25h
int 21h
pop ds
in al,21h
and al,0fdh
out 21h,al
sti
……
main endp
25
kbint proc near
push ax
push bx
in al,60h
push ax
in al,61h
mov ah,al
or al,80h
out 61h,al;送键盘应答信号
xchg ah,al
out 61h,al;复位键盘
pop ax
test al,80h
jnz ret1 ;通码时处理
通码,(60h)7=0
断码,(60h)7=1
mov bx,addr
mov [bx],al
call disp
inc bx
inc count
mov addr,bx
check,
cmp count,32
jb ret1 ;判断是否溢出
in al,21h
or al,02 ;屏蔽键盘中断
and al,7fh
out 21h,al ;允许打印机中断
call intip
ret1,
cli
mov al,20h
out 20h,al ;结束键盘中断
pop bx
pop ax
iret
kbint endp
26
intip proc near
push ax
push bx
push dx
cli
mov bx,offset message
mov addr,bx
mov dx,378h
mov al,0dh
out dx,al ;输出回车
mov dx,37ah
mov al,1dh
out dx,al ;送选通信号
jmp $+2 ;展宽选通信号
mov al,1ch
out dx,al
pop dx
pop bx
pop ax
ret
intip endp
27
prtint proc near
push ax
push bx
push dx
mov bx,addr
mov al,[bx]
mov dx,378h
out dx,al
push ax
mov dx,37ah
mov al,1dh
out dx,al
jmp $+2
mov al,1ch
out dx,al
pop ax
inc bx
mov addr,bx
cmp al,0ah
jnz ret2
in al,21h
or al,80h
out 21h,al ;屏蔽打印机中断
ret2,
mov al,20h
out 20h,al ;结束打印机中断
pop dx
pop bx
pop ax
iret
prtint endp
28
disp proc near;显示扫描码
push ax
push cx
push dx
mov ch,2
mov cl,4
nextb,rol al,cl
push ax
mov dl,al
and dl,0fh
or dl,30h
cmp dl,3ah
jl dispit
add dl,7
dispit,
mov ah,2
int 21h
pop ax
dec ch
jnz nextb
mov ah,2
mov dl,','
int 21h
pop dx
pop cx
pop ax
ret
disp endp
29
作业,
p313 8.2 8.5 8.6