8259中断程序设计实验
2020-12-09 知乎
实验题目
- 单中断请求实验:利用系统总线上中断请求信号MIR7,设计一个单一中断请求实验
- 双中断优先级实验:利用系统总线上中断请求信号MIR6和MIR7,设计一个双中断优先级应用实验,观察8253对中断优先级的控制
实验要求
- (1)单中断请求实验:单脉冲KK1+与主片8259的IR7相连。每按KK1+,进入一次中断,输出7;
(2)双中断优先级实验:单脉冲KK1+连主片8259的IR7,KK2+连其IR6。每当KK1+按下时显示“7”,每当KK2+按下显示“6”;
了解8259
中断控制器8259简介
在Intel 386EX芯片中集成有中断控制单元(ICU),该单元包含有两个级联中断控制器,一个为主控制器,一个为从控制器。该中断控制单元就功能而言与工业上标准的82C59A是一致的,操作方法也相同。从片的INT连接到主片的IR2信号上构成两片8259的级联。
在TD-PITE实验系统中,将主控制器的IR6、IR7以及从控制器的IR1开放出来供实验使用,主片8259的IR4供系统串口使用。8259的内部连接及外部管脚引出如图:
操作命令字1寄存器(OCW1)说明:
注:这里就简单的提下OCW1控制命令字的格式,ICW1–ICW4一般电脑都默认初始化了的,只不过我们自己在实验过程中需要自己编写代码初始化的,但是格式是一样的,记住模板就行了,OCW1却是会变换的,所以学习下OCW1的写法。
- OCW1简单说来就是,需要哪个中断(8259有7个,IR0-IR7),我们就把哪个中断置0,这是提醒一下,IR4都是会使用的,供系统串口使用,所以IR4那位一直是0,比如这里我们需要7号中断(IR7),那么格式就是01101111,也就是6F。
- 在这里,海轰其实一直有个疑问?为什么要设置操作命令字?操作命令字是干什么的? emmmm,说说海轰的理解:8259作为一款芯片,可以做的事情很多,但是一般来说,我们产品只需要一个功能,比如在这里就是需要7号中断。那么事先我们就需要通过程序来使得该芯片的功能确定下来。简单说来就是:确定芯片的工作方式(它要工作,首先它得知道需要干什么吧)
单中断请求流程
这个理解记住,代码就会写了!
单中断请求实验代码
CODE SEGMENT ASSUME CS:CODE START: ;DOS调用写入法 CLI ;关中断,防止硬件中断对程序的干扰 PUSH DS ;设置中断向量 MOV AX,8 MOV DX,AX ;下面几句就是CPU收到中断请求时,把需要执行的子程序的段地址、偏移地址放到中断向量中 ;为什么要这样做? ;计算机中有个规则,CPU只会得到中断类型号,然后乘4,得到其子程序入口地址,开始子程序 ;但是自定义中断,子程序是千变万化的,为了让计算机执行我们自己编写的程序,所以我们自己就需要 ;把子程序入口地址放到类型号*4的地址那去 MOV AX,OFFSET MIR7 ;取MIR7的偏移地址 MOV BX,003CH ;中断类型号为n,BX设置为4*n MOV [BX],AX ;偏移地址放入4n,4n+1单元 MOV AX,SEG MIR7 ;取MIR7的段地址 MOV [BX+2],AX ;偏移地址放入4n+2,4n+3单元 POP DS ;初始或ICW 固定模式 MOV AL,11H ;初始化ICM1 OUT 20H,AL MOV AL,08H ;初始化ICM2 OUT 21H,AL MOV AL,04H ;初始化ICM3 OUT 21H,AL MOV AL,01H ;初始化ICM4 OUT 21H,AL ;初始化OCW1 01101111,开放IR7和IR4(4是作为系统串口使用,必须接入), MOV AL,6FH ;设置OCW1,开放MIR7和IR4 OUT 21H,AL STI ;开中断 WIN:JMP WIN ;等待中断 ;子程序 MIR7: STI MOV AX,0137H ;显示字符7 INT 10H MOV AX,0120H ;显示空格 INT 10H MOV AL,20H ;中断结束命令 OUT 20H,AL IRET ;中断返回 CODE ENDS END START
解释
MOV AX,OFFSET MIR7 ;取MIR7的偏移地址 MOV BX,003CH ;中断类型号为n,BX设置为4*n MOV [BX],AX ;偏移地址放入4n,4n+1单元 MOV AX,SEG MIR7 ;取MIR7的段地址 MOV [BX+2],AX ;偏移地址放入4n+2,4n+3单元
为什么上面几行代码中地址是003C和003E?
首先我们知道子程序入口是中断类型号*4,那么IR7的中断类型号是多少呢?
从下图可以看出,IR7的中断类型号是F(0F),0F×4=003C
003E=0F×4+2
现在知道入口地址怎么来了吧 O(∩_∩)O哈哈~
为什么ICW1送入20H,而ICW2-ICW3,OCW1都送入21H呢?
MOV AL,11H ;初始化ICM1 OUT 20H,AL MOV AL,08H ;初始化ICM2 OUT 21H,AL
这也比较好理解:首先我们需要初始化ICW、OCW,就是给他们赋初值。那么第一步肯定得知道他们在哪吧,然后再赋值。8088规定的是ICW1送入地址在20H,其他在21H(别问为什么,我也不知道,按照规则办事就行)。
双中断优先级实验代码(前一个代码懂了,这一个就简单了 )
CODE SEGMENT ASSUME CS:CODE START: CLI PUSH DS ;设置中断向量 MOV AX,8 MOV DX,AX MOV AX,OFFSET MIR7 MOV BX,003CH MOV [BX],AX MOV AX,SEG MIR7 MOV [BX+2],AX MOV AX,8 ;设置中断向量 MOV DX,AX MOV AX,OFFSET SIR1 MOV BX,00C4H MOV [BX],AX MOV AX,SEG SIR1 MOV [BX+2],AX POP DS MOV AL,11H ;初始化ICW1-ICW4 OUT 20H,AL MOV AL,08H OUT 21H,AL MOV AL,04H OUT 21H,AL MOV AL,01H OUT 21H,AL MOV AL,11H ;初始化ICW1-ICW4 OUT 0A0H,AL MOV AL,30H OUT 0A1H,AL MOV AL,02H OUT 0A1H,AL MOV AL,01H OUT 0A1H,AL MOV AL,6BH ;01101011 OUT 21H,AL MOV AL,0FDH ;设置OCM1,开放MIR7和SIR1 OUT 0A1H,AL STI WIN:JMP WIN ;主程序循环 MIR7: STI MOV AX,014DH ;显示M INT 10H MOV AX,0137H ;显示7 INT 10H MOV AX,0120H ;显示空格 INT 10H MOV AL,20H OUT 20H,AL IRET SIR1: STI MOV AX,0153H ;显示S INT 10H MOV AX,0131H ;显示1 INT 10H MOV AX,0120H INT 10H ;显示空格 MOV AL,20H OUT 0A0H,AL OUT 20H,AL IRET CODE ENDS END START