2025-05-27 16:03:52 +08:00

136 lines
7.9 KiB
NASM
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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