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

文章目录

前言

一、实验任务

二、思路分析

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中断例程的分析及代码。这个实验比较简单有趣。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值