136 lines
7.9 KiB
NASM
Executable File
136 lines
7.9 KiB
NASM
Executable File
DATA SEGMENT
|
||
INT_OFF1 DW 0 ; 存储主片原来中断向量的偏移地址
|
||
INT_SEG1 DW 0 ; 存储主片原来中断向量的段地址
|
||
INT_OFF2 DW 0 ; 存储从片原来中断向量的偏移地址
|
||
INT_SEG2 DW 0 ; 存储从片原来中断向量的段地址
|
||
LED_STATE DW 00000001B ; 0|xxx|0(B组0方式)|000(指定PC0引脚)|1(置位)
|
||
DATA ENDS
|
||
|
||
STACK SEGMENT
|
||
DW 100 DUP (0) ; 定义堆栈段,大小为100字节
|
||
STACK ENDS
|
||
|
||
CODE SEGMENT
|
||
ASSUME CS:CODE, DS:DATA, SS:STACK
|
||
START:
|
||
MOV AX, DATA ; 将数据段地址存入AX寄存器
|
||
MOV DS, AX ; 将AX中的值装载到DS寄存器
|
||
MOV ES, AX ; 将AX中的值装载到ES寄存器
|
||
MOV AX, STACK ; 将堆栈段地址存入AX寄存器
|
||
MOV SS, AX ; 将AX中的值装载到SS寄存器
|
||
|
||
CLI ; 清除中断标志,禁止中断,防止在修改中断向量表过程中有中断触发
|
||
; 保存主片原来的中断向量
|
||
MOV AX, 350BH ; 获取原来的中断号为0BH的中断向量
|
||
INT 21H ; 将中断向量的偏移地址存在BX,段地址存在ES
|
||
MOV INT_OFF1, BX ; 分别将原来中断向量的偏移地址和段地址保存
|
||
MOV BX, ES
|
||
MOV INT_SEG1, BX
|
||
|
||
; 向主片装填新的中断向量
|
||
MOV DX, SEG SW_INT ; 将主片新中断向量的段地址存入DX
|
||
MOV DS, DX ; 再装到DS
|
||
MOV DX, OFFSET SW_INT ; 将主片新中断向量的偏移地址存入DX
|
||
MOV AX, 250BH ; 装填到中断向量表里中断号为0BH的中断向量
|
||
INT 21H
|
||
MOV AX, DATA ; 重新加载数据段地址
|
||
MOV DS, AX
|
||
|
||
; 保存从片原来的中断向量
|
||
MOV AX, 3572H ; 获取原来的中断号为72H的中断向量
|
||
INT 21H ; 将中断向量的偏移地址存在BX,段地址存在ES
|
||
MOV INT_OFF2, BX ; 分别将原来中断向量的偏移地址和段地址保存
|
||
MOV BX, ES
|
||
MOV INT_SEG2, BX
|
||
|
||
; 向从片装填新的中断向量
|
||
MOV DX, SEG SW_INT ; 将从片新中断向量的段地址存入DX
|
||
MOV DS, DX ; 再装到DS
|
||
MOV DX, OFFSET SW_INT ; 将从片新中断向量的偏移地址存入DX
|
||
MOV AX, 2572H ; 装填到中断向量表里中断号为72H的中断向量
|
||
INT 21H
|
||
MOV AX, DATA ; 重新加载数据段地址
|
||
MOV DS, AX
|
||
|
||
; 取消主片MIRQ3的中断屏蔽
|
||
IN AL, 21H ; 读取主片中断屏蔽寄存器
|
||
AND AL, 11110111B ; 将第3位设置为0
|
||
OUT 21H, AL ; 将修改后的值写入主片中断屏蔽寄存器
|
||
|
||
; 取消从片SIRQ10的中断屏蔽
|
||
IN AL, 0A1H ; 读取从片中断屏蔽寄存器
|
||
AND AL, 11111011B ; 将第2位设置为0
|
||
OUT 0A1H, AL ; 将修改后的值写入从片中断屏蔽寄存器
|
||
|
||
; 主程序
|
||
MOV DX, 283H ; 8255芯片的命令口
|
||
MOV AL, 10000000B ; 1|00(A组0方式)|0(PA输出)|0(PC4-7输出)|0(B组0方式)|0(PB输出)|0(PC0-3输出)
|
||
OUT DX, AL
|
||
MOV DX, 283H ; 8255芯片的命令口
|
||
MOV AX, LED_STATE ; 输出控制LED的状态
|
||
OUT DX, AL
|
||
|
||
XOR DX, DX ; 将DX置0
|
||
L1: STI ; 设置中断标志
|
||
CMP DX, 10 ; 判断中断是否已触发了10次
|
||
JNE L1
|
||
|
||
CLI ; 清除中断标志,禁止中断,防止在修改中断向量表过程中有中断触发
|
||
; 恢复主片原来的中断向量
|
||
MOV DX, INT_SEG1 ; 将主片原中断向量的段地址存入DX
|
||
MOV DS, DX ; 再装到DS
|
||
MOV DX, INT_OFF1 ; 将主片原中断向量的偏移地址存入DX
|
||
MOV AX, 250BH ; 装填到中断向量表里中断号为0BH的中断向量
|
||
INT 21H
|
||
MOV AX, DATA ; 重新加载数据段地址
|
||
MOV DS, AX
|
||
|
||
; 恢复从片原来的中断向量
|
||
MOV DX, INT_SEG2 ; 将从片原中断向量的段地址存入DX
|
||
MOV DS, DX ; 再装到DS
|
||
MOV DX, INT_OFF2 ; 将从片原中断向量的偏移地址存入DX
|
||
MOV AX, 2572H ; 装填到中断向量表里中断号为72H的中断向量
|
||
INT 21H
|
||
MOV AX, DATA ; 重新加载数据段地址
|
||
MOV DS, AX
|
||
|
||
; 设置主片的中断屏蔽
|
||
IN AL, 21H ; 读取主片中断屏蔽寄存器
|
||
OR AL, 00001000B ; 将第3位设置为1
|
||
OUT 21H, AL ; 将修改后的值写入主片中断屏蔽寄存器
|
||
|
||
; 设置从片的中断屏蔽
|
||
IN AL, 0A1H ; 读取从片中断屏蔽寄存器
|
||
OR AL, 00000100B ; 将第2位设置为1
|
||
OUT 0A1H, AL ; 将修改后的值写入从片中断屏蔽寄存器
|
||
STI ; 设置中断标志
|
||
|
||
; 返回DOS
|
||
MOV AX, 4C00H
|
||
INT 21H
|
||
|
||
; 中断服务程序
|
||
SW_INT PROC NEAR
|
||
PUSH AX ; 保护主程序运行状态
|
||
CLI ; 清除中断标志,禁止中断程序执行过程中跳转到其他中断程序
|
||
INC DX ; 触发计数加1
|
||
|
||
PUSH DX ; 保护DX
|
||
MOV AX, LED_STATE
|
||
ADD AX, DX ; DX的末位会随着其增加交替为0和1
|
||
AND AX, 00000001B ; 取末位控制PC0为0或1
|
||
MOV DX, 283H ; 从而实现灯的亮灭交替
|
||
OUT DX, AL
|
||
POP DX ; 恢复DX
|
||
|
||
MOV AL, 20H ; 向主片发送EOI指令
|
||
OUT 20H, AL
|
||
MOV AL, 62H ; 向从片发送EOI指令
|
||
OUT 0A0H, AL
|
||
STI ; 设置中断标志,允许跳转到中断程序
|
||
POP AX ; 恢复主程序运行状态
|
||
IRET
|
||
SW_INT ENDP
|
||
|
||
CODE ENDS
|
||
END START |