8259A
芯片方面的内容就不再多说。大家自己参考相关书籍就可以了。8259A主要用于实现程序的中断控制。中断控制对于计算机的功能而言,是非常基础也是十分重要的,例如操作系统里并行程序间的切换,这就是典型的中断控制,其中涉及到了开关中断,系统栈,用户栈,通用寄存器,系统状态寄存器(psw)的现场信息保存。有兴趣的同学可以去做详细了解。
那么实际操作中,我们如何用汇编语言实现中断程序的控制呢?主要是以下的流程:
首先,对8259A进行初始化。用out指令往CS引脚连接的控制端口进行写操作。需要注意,8259A要对4个ICW进行写操作:
1.写ICW1,设置8259A是否为级联方式,触发信号类型,是否使用ICW4
2.写ICW2,设置中断类型码(中断类型码,中断向量对8259的理解非常重要!大家一定要透彻理解)
3.写ICW3,如果是级联,则要对主片和从片分别写入
4.写ICW4,设置特殊全嵌套方式,缓冲方式,自动结束中断方式,选择CPU
至此,初始化完成。
初始化完成后进行中断向量的设置,然后写对应的中断处理程序就可以了。
以笔者的一条微机实验题为例:
题目:编写中断试验程序:主程序通过8255的PB口输出0FFH,使数据灯D0~D7全亮;IR6中断服务程序使绿灯亮(红灯灭);延时一段时间后返回主程序;IR7中断服务程序使红灯亮(绿灯灭);延时一段时间后返回主程序。
- 要求:按单脉冲开关KK1+响应IR6中断请求;按单脉冲开关KK2+响应IR7中断请求。
CODE SEGMENT
ASSUME CS:CODE
START:
MOV AX, 0000H
MOV DS, AX ;手动指定用户程序区的起始位置,可以不指定,默认为0000HMOV DX, 0646H ;8255控制端口地址,与选取的IOY端口有关,详见实验一
MOV AL, 90H ;8255控制字,90H=10010000B,表示A口输入,B口输出。
OUT DX, AL ;将上述控制字写入控制端口
MOV DX, 0642H ;8255B口地址
MOV AL,0FFH
OUT DX,AL ;输出FFH=11111111B,将D7-D0点亮MOV AX, OFFSET MIR6 ;取中断服务程序的偏移地址
MOV SI, 0038H ;中断号6的向量起始地址,见实验讲义P48
MOV [SI], AX ;将服务程序地址填入中断向量(占两个字节)
MOV AX, CS ;取段地址
MOV SI, 003AH ;中断向量后移两个字节等待存入段地址
MOV [SI], AX ;将段地址存入中断向量(占两个字节)
;中断向量共四个字节大小,分别存服务程序入口地址和段地址
MOV AX, OFFSET MIR7
MOV SI, 003CH
MOV [SI], AX
MOV AX, CS
MOV SI, 003EH
MOV [SI], AX
;填入MIR7的中断向量,同上
CLI ;屏蔽所有可屏蔽中断,准备写入命令字
MOV AL, 11H ;主片8255端口地址详见实验讲义P44
OUT 20H, AL ;命令字ICW1,11H=00010001B
MOV AL, 08H
OUT 21H, AL ;命令字ICW2,08H=00001000B
MOV AL, 04H
OUT 21H, AL ;命令字ICW3,04H=00000100B
MOV AL, 01H
OUT 21H, AL ;命令字ICW4,01H=00000001B
MOV AL, 3FH
OUT 21H, AL ;命令字OCW1,3FH=00111111B
STI ;控制字写入完成,允许中断,结束CLI
;OCW1命令字表示除IR6,IR7中断外其余中断均被屏蔽
;其余命令字含义请对照实验讲义P45-P48
AA1:
MOV DX, 0642H
MOV AL, 0FFH
OUT DX, AL
JMP AA1
;相当于主程序,表示循环点亮D7-D0
MIR6:
MOV DX, 0642H
MOV AL, 0F0H
OUT DX, AL
;按下KK1+进入MIR6中断,只点亮绿灯
MOV AL, 20H ;命令字OCW2,20H=00100000B,表示结束中断
OUT 20H, AL ;写入OCW2,结束中断MOV CX,0FFFFH ;CX为计数寄存器,确定循环次数
L1:
LOOP L1
MOV CX,0FFFFH
L2:
LOOP L2
MOV CX,0FFFFH
L3:
LOOP L3
MOV CX,0FFFFH
L4:
LOOP L4
;L1-L4为空循环,作用为延迟时间,改为多层循环或子程序更好
IRET
;中断返回指令,回到主程序发生中断的位置
MIR7:
MOV DX, 0642H
MOV AL,0FH
OUT DX,AL
MOV AL,20H
OUT 20H,AL
MOV CX,0FFFFH
L5:
LOOP L5
MOV CX,0FFFFH
L6:
LOOP L6
MOV CX,0FFFFH
L7:
LOOP L7
MOV CX,0FFFFH
L8:
LOOP L8
IRET
;按下KK2+进入MIR7中断,只点亮红灯,其余同上
CODE ENDS
END START