📄 interupt.asm
字号:
ioport equ 5400H-280H
IOPORTE EQU 5000H
DATA SEGMENT
MESSAGE DB 'THIS IS A 8259 INTERRUPT!',0AH,0DH,'$'
FLAG DB 0
INTMASK DB ?
CSREG DW ?
IPREG DW ?
DATA ENDS
STACK SEGMENT
STA DB 50 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:CLI
MOV DX, IOPORTE+68H
IN AX,DX
OR AX,0900H
OUT DX,AX
MOV AX,DATA
MOV DS,AX
;8253初始化
MOV DX,ioport+283H
MOV AL,00110111B ;通道0控制字,先读写低字节,后高字节,方式3,BCD计数
OUT DX,AL
MOV DX,ioport+280H
MOV AL,00H
OUT DX,AL
MOV AL,10H
OUT DX,AL
MOV DX,ioport+283H
MOV AL,01110111B ;通道1控制字,先读写低字节,后高字节,方式3,BCD计数
OUT DX,AL
MOV DX,ioport+281H
MOV AL,00H
OUT DX,AL
MOV AL,10H
OUT DX,AL
MOV AX,350BH
;35号功能调用,取0f号中断向量送ES:BX
INT 21H
MOV AX,ES
MOV CSREG,AX ;将ES保存到CSREG中
MOV IPREG,BX ;将BX保存到IPREG中
PUSH DS ;将DS入栈保存
MOV AX,CS
MOV DS,AX ;将CS存入DS中
MOV DX,OFFSET INT_PROC ;设置新的中断向量
MOV AX,250BH
;25号功能调用,设置中断向量至ES:BX,AL存中断类型号
INT 21H
POP DS ;将DS内容出栈
IN AL,21H ;取中断屏蔽寄存器的内容
;MOV INTMASK,AL ;将AL保存到INTMASK
;MOV AL,11110111B ;允许IR7中断
AND AL,11110111B
OUT 21H,AL
IN AL,0A1H
AND AL,11110111B
OUT 0A1H ,AL
MOV BX,5H ;设置循环次数
STI ;开中断
LOP: MOV AL,FLAG ;等待中断结束
CMP AL,01H ;判断FLAG标志位是否为1
JNZ LOP ;如果不为1,继续等待
CLI ;关中断
MOV AL,INTMASK ;将AL内容恢复
OUT 21H,AL
MOV DX,IPREG ;将DX内容恢复
MOV AX,CSREG ;将DS内容恢复
MOV DS,AX
MOV AX,250BH
;25号功能调用,设置中断向量至ES:BX,AL存中断类型号
INT 21H
STI ;开中断
MOV DX, IOPORTE+68H
IN AX,DX
AND AX,0F7FFH
OUT DX,AX
MOV AX,4C00H ;4C号功能调用,带返回码结束
INT 21H
INT_PROC:
PUSH DS ;将DS入栈
MOV AX,DATA
MOV DS,AX ;DS重新指向数据段
MOV DX,OFFSET MESSAGE ;打印提示信息
MOV AH,09H
INT 21H
MOV AL,20H ;中断结束
OUT 20H,AL
OUT 0A0H,AL
DEC BX ;循环次数减1
JNZ NEXT ;BX减到0,则转至执行NEXT
MOV AL,01H ;将FLAG标志位设为1
MOV FLAG,AL
MOV AL,11111111B ;关闭中断对应屏蔽位
OUT 21H,AL
NEXT: POP DS ;将DS出栈
IRET ;中断返回
CODE ENDS
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -