您的位置:首页 > 其它

花了几个钟头才写好一个利用直接定址表的中断处理程序

2007-07-05 21:12 405 查看
王爽《汇编语言》第十六章的实验,我做了一些改动。


;21:02 2007-7-5


assume cs:codesg




datasg segment


endl EQU <0dh,0ah>


function0 db endl,"This Int 7ch function is:$"


function1 db endl,"(1) Cls $"


function2 db endl,"(2) Set FrontColor$"


function3 db endl,"(3) Set BackColor$"


function4 db endl,"(4) Scroll Up$"


function5 db endl,"(5) Exit$"


inputf db endl,endl,"Please Input function number:$"


inputc db endl,endl,"Please Input color(0-8):$"


errors db endl,endl,"Input Error!Please Input the number(1-5),color(0-8)",endl,endl,'$'


datasg ends




stack segment


dw 16 dup (0)


stack ends




codesg segment




start:


mov ax,stack


mov ss,ax


mov sp,32


mov ax,datasg


mov ds,ax




;/**////////////////////////////////////////////////


;安装int 7ch中断处理程序


mov ax,0


mov es,ax


cli


mov word ptr es:[7ch*4],offset setscreen


mov es:[7ch*4+2],cs


sti




;/**/////////////////////////////////////////////////


int 7ch




mov ax,4c00h


int 21h






;/**/////////////////////////////////////////////////


;int 7ch中断处理程序代码




setscreen:


jmp short showfc


table:


dw 0,sub1,sub2,sub3,sub4 ;直接定值表,第一个0为补充地址,使得输入1调用sub1。




showfc:


push ax


push dx


push bx


push cx




;显示功能提示


showfc1:


mov ah,9 ;int 21h 9号功能为在标准输出上显示以$结尾的字符串,DS:DX指向字符串偏移地址。


mov dx,offset function0


int 21h


mov dx,offset function1


int 21h


mov dx,offset function2


int 21h


mov dx,offset function3


int 21h


mov dx,offset function4


int 21h


mov dx,offset function5


int 21h




mov dx,offset inputf


int 21h




;提示输入功能号码


inputfc:


mov ah,1


int 21h ;int 21h 1号功能为从标准输入(键盘)读取一个字符的ASCII码到al,无输入时等


;待,回显输入字符。


sub al,30h ;输入数字ASCII码减30h转换为十进制值。


mov bh,al


cmp bh,5 ;范围判断


ja error


cmp bh,5 ;5号功能为退出。


je sret


cmp bh,0 ;范围判断


jb error


cmp bh,2 ;如果是2 3号功能则提示输入颜色值。


je inputcolor


cmp bh,3


je inputcolor


jmp short set




inputcolor:


mov ah,9


mov dx,offset inputc


int 21h


mov ah,1


int 21h


sub al,30h


cmp al,8 ;范围判断


ja error


cmp al,0


jb error ;范围判断




set:
mov ah,bh


mov bl,ah


mov bh,0


add bx,bx ;根据输入的功能号码来确定TABLE中子程序的偏移地址。


call word ptr table[bx] ;调用子程序


jmp short showfc1 ;功能循环




sret:


pop cx


pop bx


pop dx


pop ax


iret




error:
call sub1


mov ah,9


mov dx,offset errors


int 21h


jmp short showfc1




sub1:


push bx


push cx


push es


mov bx,0b800h


mov es,bx


mov bx,0 ;显存偶数地址为字符。


mov cx,2000 ;显存一页4000字节,偶数字节为2000个。


sub1s:


mov byte ptr es:[bx],' ' ;用空格代替原先字符,相当于清除原字符。


add bx,2


loop sub1s


pop es


pop cx


pop bx


ret






sub2:


push bx


push cx


push es


mov bx,0b800h


mov es,bx


mov bx,1 ;显存奇数地址为颜色值。


mov cx,2000 ;显存一页4000字节,奇数字节为2000个。


sub2s:


and byte ptr es:[bx],11111000b ;颜色值中0 1 2位为前景色RGB,先清除掉。


or es:[bx],al ;再or上我们输入的al值,则得到我们需要的前景色。


add bx,2


loop sub2s


pop es


pop cx


pop bx


ret




sub3:


push bx


push cx


push es


mov cl,4


shl al,cl


mov bx,0b800h


mov es,bx


mov bx,1


mov cx,2000


sub3s:


and byte ptr es:[bx],10001111b ;颜色值中7 6 5位为背景色RGB。


or es:[bx],al


add bx,2


loop sub3s


pop es


pop cx


pop bx


ret




sub4:


push cx


push si


push di


push es


push ds


mov si,0b800h


mov es,si


mov ds,si


mov si,160 ;显存一页25行(0-24),160列(0-159),这里的160为下一行开头的第一列。


mov di,0 ;上一行开头。SI,DI顺序递增~


cld


mov cx,24 ;只需要复制后面的24行,开头第一行不要了。


sub4s:


push cx


mov cx,160 ;列数还是要够160的,这里是循环次数,注意和上面的区别。


rep movsb


pop cx


loop sub4s




mov cx,80 ;一行160列,偶数列为80,偶数列也即是字符所在列。


mov si,0


sub4s1:


mov byte ptr [160*24+si],' ' ;最后一行上移了,原来行的字符要清除掉。


add si,2


loop sub4s1


pop ds


pop es


pop di


pop si


pop cx


ret




codesg ends


end start

唉,做个这么简单的东西都要花这么长时间,年轻人的话估计有45分钟也就搞定调试完了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐