《汇编语言》王爽(第四版) 第十五章 实验15

您所在的位置:网站首页 汇编语言第四版王爽课后答案实验10 《汇编语言》王爽(第四版) 第十五章 实验15

《汇编语言》王爽(第四版) 第十五章 实验15

2024-06-12 08:45| 来源: 网络整理| 查看: 265

文章目录

前言

一、实验任务

二、思路分析

1.编写9号中断例程

2.安装9号中断例程

三、完整代码

总结

前言

本文是王爽老师《汇编语言》(第四版) 第十五章 实验15 安装新的int 9中断例程(按下并松开A键后显示满屏的A,其它键照常处理) 的分析及代码。

一、实验任务

安装一个新的int 9中断例程,功能:在dos下,按下“A”键后,除非不再松开,如果松开,就显示满屏幕的“A”,其它的键照常处理。

最终效果如图,按下并松开A键后显示满屏的“A”。

二、思路分析

实现的整体思路:

1.写一个新的9号中断例程,其中调用系统BIOS的9号中断例程,之后再对“A”键输入进行处理;

2.将自定义的9号中断例程安装在系统0:204H处,而BIOS的9号中断例程入口地址,存放在0:200H处。

1.编写9号中断例程

这个自定义的中断例程要做的事情:

① 从端口读取键盘输入;

②调用系统提供的int 9H中断例程,进行与硬件相关的处理;

③如果输入的是“A”,那么就进行处理,使屏幕上所有字符都变为“A”,即ASCII码的41H。

注意:调用BIOS的中断例程时应该用“dword ptr”而不是“word ptr”。

代码如下。

do9H: ;自定义9号中断例程 功能:松开A键则显示满屏幕的A,其它键照常处理 ;参数:无 ;返回:无 push ax push bx push es push cx ;1.从60H端口接收键盘输入 in al,60H ;2.调用BIOS的9号中断例程 pushf ;将标志寄存器压入栈 call dword ptr cs:[200H] ;0:200H处存放BIOS的9号中断例程的入口地址 ;3.对“A”键进行处理 cmp al,9EH ;A的通码为1EH,断码为9EH jne do9H_iret mov ah,'A' ;若按下的是A键,则显示满屏的A mov bx,0B800H mov es,bx mov bx,0 ;当前字符偏移地址 mov cx,2000 ;一屏能显示2000个字符 s_do9H: mov es:[bx],ah add bx,2 loop s_do9H do9H_iret: ;程序返回 pop cx pop es pop bx pop ax iret do9H_end:nop 2.安装9号中断例程

安装中断例程的代码之前写过,但这里多了一步,要在自定义的中断例程中调用BIOS的中断例程,因此要写一个新的install子程序。

注意,因为BIOS提供的int 9H中断例程还要被调用,所以要先将BIOS的中断例程入口地址保存起来(中断向量表中取出,保存到0:200H处),之后再将自定义的9号中断例程的入口地址写入中断向量表。

代码如下。

install: ;功能:将自定义的9号中断例程安装在0:204H处,并将BIOS的9号中断例程入口地址复制在0:200H处 ;参数:无 ;返回:无 push ax push ds push si push es push di push cx ;1.将自定义的9号中断例程程序段复制到0:204H处 push cs ;ds:si指向要复制的源地址起始处 pop ds mov si,offset do9H mov ax,0 ;es:di指向复制的目标地址起始处 mov es,ax mov di,204H mov cx,offset do9H_end - offset do9H ;要复制的数据长度 cld ;设置DF=0,正向传输 rep movsb ;2.将BIOS的9号中断例程入口地址复制到0:200H处 mov ax,0 mov es,ax push es:[9*4] ;偏移地址 pop es:[200H] push es:[9*4+2] ;段地址 pop es:[202H] ;3.将自定义的9号中断例程的入口地址添加到中断向量表中 cli ;设置IF=0,不响应可屏蔽中断 相当于一个锁,避免地址设置错误 mov word ptr es:[9*4],204H ;偏移地址 mov word ptr es:[9*4+2],0H ;段地址 sti ;设置IF=1,响应可屏蔽中断 pop cx pop di pop es pop si pop ds pop ax ret 三、完整代码

最终效果还是不错的,挺好玩,哈哈。

自定义的中断例程中处理的是“A”的断码,其实A键和其它键还是可以正常使用(因为一般键入字符的功能检测的都是键盘输入的通码而不是断码),只不过当松开A键以后屏幕上全是“A”,覆盖了原先的显示内容。

如果想要清屏,那么需要“cls”命令然后回车,搞定。

以下是完整代码。

assume cs:code stack segment db 64 dup(0) stack ends code segment start: mov ax,stack ;设置栈顶 mov ss,ax mov sp,40H call install mov ax,4c00H int 21H install: ;功能:将自定义的9号中断例程安装在0:204H处,并将BIOS的9号中断例程入口地址复制在0:200H处 ;参数:无 ;返回:无 push ax push ds push si push es push di push cx ;1.将自定义的9号中断例程程序段复制到0:204H处 push cs ;ds:si指向要复制的源地址起始处 pop ds mov si,offset do9H mov ax,0 ;es:di指向复制的目标地址起始处 mov es,ax mov di,204H mov cx,offset do9H_end - offset do9H ;要复制的数据长度 cld ;设置DF=0,正向传输 rep movsb ;2.将BIOS的9号中断例程入口地址复制到0:200H处 mov ax,0 mov es,ax push es:[9*4] ;偏移地址 pop es:[200H] push es:[9*4+2] ;段地址 pop es:[202H] ;3.将自定义的9号中断例程的入口地址添加到中断向量表中 cli ;设置IF=0,不响应可屏蔽中断 相当于一个锁,避免地址设置错误 mov word ptr es:[9*4],204H ;偏移地址 mov word ptr es:[9*4+2],0H ;段地址 sti ;设置IF=1,响应可屏蔽中断 pop cx pop di pop es pop si pop ds pop ax ret do9H: ;自定义9号中断例程 功能:松开A键则显示满屏幕的A,其它键照常处理 ;参数:无 ;返回:无 push ax push bx push es push cx ;1.从60H端口接收键盘输入 in al,60H ;2.调用BIOS的9号中断例程 pushf ;将标志寄存器压入栈 call dword ptr cs:[200H] ;0:200H处存放BIOS的9号中断例程的入口地址 ;3.对“A”键进行处理 cmp al,9EH ;A的通码为1EH,断码为9EH jne do9H_iret mov ah,'A' ;若按下的是A键,则显示满屏的A mov bx,0B800H mov es,bx mov bx,0 ;当前字符偏移地址 mov cx,2000 ;一屏能显示2000个字符 s_do9H: mov es:[bx],ah add bx,2 loop s_do9H do9H_iret: ;程序返回 pop cx pop es pop bx pop ax iret do9H_end:nop code ends end start 总结

本文是王爽老师《汇编语言》(第四版) 第五章 实验15 安装新的int 9中断例程的分析及代码。这个实验比较简单有趣。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3