Advertisement

《汇编语言》- 读书笔记 - 第15章-外中断-实验15 安装新的 int9 中断例程

阅读量:

《汇编语言》- 读书笔记 - 第15章-外中断-实验15 安装新的 int9 中断例程

  • 需求
  • 代码
  • 运行效果

需求

在DOS系统中配置一个新增的中断例程变量名 int 9 ,其功能如下:当按压A键时,在继续按压的情况下才会显示满屏的A字符;否则(即松开)则执行其他操作。其他按键仍能正常工作。

说明:当按压一个键时所生成的扫描码即为通行码,在松开同一个键时所生成的扫描码则被称为断码。

代码

复制代码
    assume cs:code
    stack segment
    	db 128 dup(0)
    stack ends
    
    code segment
     start: mov ax,stack		; 设置栈段和栈顶位置
    		mov ss,ax
    		mov sp,128
    		
    		;----------- 打个小补丁。避免重复运行后搞丢 int9 导致输入瘫痪 -----------
    		mov ax,0
    		mov ds,ax
    		mov ax,ds:[204h]
    		cmp ax,5350h		; 判断 ds:[204]=5053 则已安装过(值是调试运行查的)
    		je ok
    		
    		; -------- 安装: 复制中断例程到目标内存 -------
    		mov ax,cs			;设置 ds:si 指向源地址
    		mov ds,ax
    		mov si,offset int9
    		mov ax,0			;设置 es:di 指向目的地址
    		mov es,ax
    		mov di,204h			
    		mov cx,offset int9end-offset int9	;设置 cx为传输长度
    		cld					;设置传输方向为正。movsb中si,di递增
    		rep movsb			;重复复制数据次数由 cx 控制
    		; -------- 安装: 复制中断例程到目标内存 -------
    		
    		; ---------- 备份原 int9 入口到 [0:200~0203] ----------
    		push es:[9*4]
    		pop es:[200h]
    		push es:[9*4+2]
    		pop es:[202h]
    		; ---------- 备份原 int9 入口到 [0:200~0203] ----------
    		
    		; ---------- 设置中断向量表 ----------
    		cli							; 临时屏蔽中断
    		mov word ptr es:[9*4],204h	; 设置的偏移地址(0~3用来存原int9地址了)
    		mov word ptr es:[9*4+2],0	; 设置的段地址
    		sti							; 恢复中断
    		; ---------- 设置中断向量表 ----------
    
    	ok:	mov ax,4c00h
    		int 21h
    
    ; =======================================================	
    ; --------------------- 子程序 int 9  -------------------
    ; 调用原 int 9 获取扫描码,松开 A 显示满屏幕的 A
    ; -------------------------------------------------------
    ; 参数: 无
    ; 返回: 无
    ; -------------------------------------------------------
    int9:
    		push ax 		; 备份寄存器
    		push bx
    		push cx
    		push es
    		
    		in al,60h		; 从60h端口读取数据
    		
    		; 模拟 int 指令,用 call 调用原 int 9
    		pushf						; 进入中断后 IF、TF已经是0 直接入栈即可
    		call dword ptr cs:[200h] 	; 调用原来的 int 9 中断例程
    		
    		cmp al,9eh		; 判断是否 A 键松开
    		jne int9ret		; 如果不是直接结束
    
    		mov ax,0b800h	; 设置显存
    		mov es,ax
    		mov bx,0
    		mov cx,2000
    		mov ah,00000111b
    	s:	mov al,65
    		mov word ptr es:[bx],ax
    		add bx,2
    		loop s
    	
    int9ret:pop es			; 还原寄存器
    		pop cx
    		pop bx
    		pop ax
    		iret			; 返回
    int9end:nop
    
    ; --------------------- 子程序 int 9 ------------------
    ; =======================================================
    code ends
    end start

运行效果

在这里插入图片描述

全部评论 (0)

还没有任何评论哟~