花了几个钟头才写好一个利用直接定址表的中断处理程序
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分钟也就搞定调试完了。
;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分钟也就搞定调试完了。
相关文章推荐
- 利用BIOS中断或DOS中断实现一个显示当前时间的程序
- 利用BIOS中断或DOS中断实现一个电子表的程序,要求精确到秒
- 《c primer pius》第十章第6题,编写一个程序,初始化一个二维double数组,并利用练习2中的任一函数来把这个数组复制到另一个二维数组(因为二维数组是数组的数组,所以可以使用处理一维数组的
- SAP ABAP/4学习---如何给写好的一个程序分配事务代码,用户可以直接通过事务码来访问程序.或者加入收藏夹(9)
- TI CC2530基础实验(GPIO通用I/O中断操作——一个中断处理程序处理一个端口的多个中断)
- 编写一个控制台程序,能够处理以下命令,利用args
- 一个51单片机比较综合的程序(包括了串口通信,io控制,字符串处理,中断处理),仅供自己以后参考
- 利用文件锁保证一个程序最多只有一份拷贝在运行
- 数据集处理技术文档_DataReader(DataAdapter)转换到DataSet的.NET技术(介绍一个已经写好的实用类)
- java 利用注释和反射写一个简单的SQL语句拼接程序,很简单初学者
- 一个中断产生和处理的完整流程,以UD2指令产生的#UD中断为例。
- 利用ffmpeg切割与合并视频(一)调用ffmpeg程序直接切割
- 中断处理程序不能使用printf的本质
- mysql 利用自增数据项的方法,对同一个表有某种关联的数据进行处理。(利用增加一项的方法)
- 8、与字符串处理相关的几个程序
- js 利用throw 写的一个小程序
- 利用反射获得委托和事件以及创建委托实例和添加事件处理程序
- 利用vc 6.0目录下的cl.exe直接编译程序的方法[整理]
- 《Linux设备驱动开发详解》-- Linux中断处理程序架构和Linux中断编程
- 题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。例如: 153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。 1.程序分析:利用f