下面,我们安装一个新的int 9中断例程,使得原int 9中断例程的功能得到扩展。 ......
任务:安装一个新的int 9中断例程。
功能:在DOS下,按F1键后改变当前屏幕的显示颜色,其他的键照常处理。
我们进行一下分析。
(1)改变屏幕的显示颜色
mov ax,Ob800h mov es,ax mov bx, 1 mov cx,2000 s:inc byte ptr es:[bx】 add bx,2 loop s
(2)其他键照常处理
可以调用原int 9中断处理程序,来处理其他的键盘输入。
(3)原int 9中断例程入口地址的保存
因为在编写的新int 9中断例程中要调用原int 9中断例程,所以,要保存原int 9中断例程的入口地址。保存在哪里?显然不能保存在安装程序中,因为安装程序返回后地址将丢失。我们将地址保存在0:200单元处。
(4)新int 9中断例程的安装
这个问题在前面己经详细讨论过。我们可将新的int 9中断例程安装在0:204处。
完整的程序如下。
assume cs:code stack segment db 128 dup(0) stack ends code segment start: mov ax,stack mov ss,ax mov sp,128 mov ax,code mov ds,ax mov ax,0 mov es,ax mov si,offset int9 ;设置ds:si指向源地址 mov di,204h ;设置es:di指向目的地址 mov cx,offset int9end-offset int9 ;设置CX为传输长度 cld ;设置传输方向为正 rep movsb push es:[9*4] pop es:[200h] push es:[9*4+2] pop es:[202h] cli ;禁止中断,防止赋值时有中断发生,产生错误 mov word ptr es:[9*4],204h mov word ptr es:[9*4+2],0 sti ;允许中断 mov ax,4c00h int 21h int9: push ax push bx push cx push es in al,60h pushf call dword ptr cs:[200h] cmp al,3bh ;F1的扫描码为3bh jne int9ret mov ax,0b800h mov es,ax mov bx,1 mov cx,2000 s:inc byte ptr es:[bx] add bx,2 loop s int9ret:pop es pop cx pop bx pop ax iret int9end: nop code ends end start
这一章中,我们通过对键盘输入的处理,讲解了CPU对外设输入的通常处理方法。
(l)外设的输入送入端口;
(2)向CPU发出外中断(可屏蔽中断)信息;
(3) CPU检测到可屏蔽中断信息,如果IF=1, CPU在执行完当前指令后响应中断,
执行相应的中断例程;
(4)可在中断例程中实现对外设输入的处理。
端口和中断机制,是CPU进行I/O的基础。
安装新的int 9中断例程
安装一个新的int 9中断例程,功能:在DOS下,按下“A”键后,除非不再松开,如果松开,就显示满屏幕的“A",其他的键照常处理。
提示,.按下一个键时产生的扫描码称为通码,松开一个键产生的扫描码称为断码。断码=通码+80h
assume cs:code stack segment db 128 dup (0) stack ends code segment start: ;设置栈顶ss:sp指向 mov ax,stack mov ss,ax mov sp,128 ;将原中断向量表中的9号中断处理程序地址存到0:[200]地址 mov ax,0 mov es,ax;es:di目标地址 mov di,200h mov ds,ax mov si,[9*4];ds:si源地址 mov cx,4 cld rep movsb ;将编写的新的int9中断处理程序放到0:[204]地址 mov ax,cs mov ds,ax mov si,offset int9 mov cx,offset int9end-offset int9 cld rep movsb ;更改中断向量表设置9号处理程序新的地址 cli mov word ptr es:[9*4],204h mov word ptr es:[9*4+2],0 sti mov ax,4c00h int 21h int9: push ax push es push cx push bx in al,60h pushf call dword ptr cs:[200h] ;调用原来的int9中断处理程序 cmp al,1eh+80h ;松开按键产生的断码 jne int9ret mov ax,0b800h mov es,ax mov cx,2000 mov bx,0 ;松开A键全屏显示A s: mov byte ptr es:[bx],'A' add bx,2 loop s int9ret: pop bx pop cx pop es pop ax iret int9end: nop code ends end start
指令系统总结
我们对8U86CPLT的指令系统进行一下总结。读者若要详细了解8086指令系统中的各个指令的用法,可以查看有关的指令手册。
8086CPU提供以下几大类指令
1、数据传送指令
比如,mov, push: pop, pushf, popf, xchg等都是数据传送指令,.这些指令实现寄存器和内存、寄
存器和寄存器之间的单个数据传送。
2.算术运算指令
比如,add, sub, adc: sbb; inc. dec. cmp; iznul, idiv, aaa等都是算术运算指令,这些指令实现寄存器和内存中的数据的算数运算。它们的执行结果影响标志寄存器的sf, zf, of, cf, pf, of位.
3.逻辑指令
比如,and, or, not; xor, test, shl, shr, sal、二、rol, ror: rcl, rcr等都是逻辑指令。除了not指令外,它们的执行结果都影响标志寄存器的相关标志位。
4.转移指令
可以修改IP,或同时修改CS和IP的指令统称为转移指令。转移指令分为以下几类。
(I)无条件转移指令,比如,jmp;
(2)条件转移指令,比如,jcxz, je, jb, ja, jnb, jna等;
(3)循环指令,比如,loop;
(4).过程,比如,call; ret} retf:-
(5)中断,比如,int, irete
5.处理机控制指令
这些指令对标志寄存器或其他处理机状态进行设置,比如,cld, std, c1, sti, nop, clc, core,
stc, hlt, wait, esc, lock等都是处理机控制指令。
6.串处理指令
这些指令对内存中的批量数据进行处理,比如,movsb, movsw, corps. seas. lode, sko,等。若要使用这些指令方便地进行批量数据的处理,则需要和却、reps, repne等前缀指令配合使用。