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