1.直接贴上代码:
;实现根据不同的功能号,完成程序的跳转
;--1--int7ch实现显示功能菜单
;--2--外中断接收,按键输入
;--3--子程序实现具体功能
assume cs:code,ss:stack
;数据段,提供显示
;栈段,用以暂存信息
stack segment stack
db 128 dup(0)
stack ends
code segment
start:
;--1-- 开始 首先在7ch里实现基本的功能菜单显示功能--
;寄存器初始化
mov ax,stack
mov ss,ax
mov sp,128
mov ax,cs
mov ds,ax
mov si,offset display
mov ax,0
mov es,ax
mov di,200h ;安装到0:200h处
;安装中断程序
mov cx,offset displayEnd - offset display
cld
rep movsb
;设置中断向量表
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0
;退回dos
;调用7ch号中断
; int 7ch ; 后挪-----=
;--1-- 结束 首先在7ch里实现基本的功能菜单显示功能--
;--2-- 开始 外中断接收,按键输入,功能实现
;上面的操作是规范的,寄存器是干净的,栈也是干净的,没有关联性,可以放心用
;安装中断程序
mov ax,cs
mov ds,ax
mov si,offset int9
mov ax,0
mov es,ax
mov di,200h + offset displayEnd - offset display + 14h
mov cx,offset int9End - offset int9
cld
rep movsb
;保存原来的int9中断程序的入口地址
mov di,200h + offset displayEnd - offset display + 10h
push es:[9*4]
pop es:[di]
mov di,200h + offset displayEnd - offset display + 12h
push es:[9*4+2]
pop es:[di]
;设置中断向表
cli
mov word ptr es:[9*4],200h + offset displayEnd - offset display + 14h
mov word ptr es:[9*4+2],0
sti
;--2-- 结束 外中断接收,按键输入,功能实现
;中断调用,子程序调用区
;退回dos
int 7ch
mov ax,4c00h
int 21h
;编写新的int9中断处理程序
int9:
; jmp short set
; table dw sub1
set:
push ax
push cx
push es
push di
in al,60h
;调用原来的中断程序,处理相关
pushf
mov di,200h + offset displayEnd - offset display + 10h
call dword ptr cs:[di]
mov ah,al
cmp ah,02h+80h ;按键1的断码
jb int9ret
cmp ah,05h+80h ;按键4的断码
ja int9ret
mov bl,ah
sub bl,81h
cmp bl,1
je do1
cmp bl,2
je do2
cmp bl,3
je do3
cmp bl,4
je do4
do1:
call sub1
jmp short int9ret
do2:
call sub2
jmp short int9ret
do3:
call sub3
jmp short int9ret
do4:
call sub4
jmp short int9ret
int9ret:
pop di
pop es
pop cx
pop ax
iret
sub1:
push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,0
mov cx,2000
sub1s:
mov byte ptr es:[bx],' '
add bx,1
mov byte ptr es:[bx],0
add bx,1
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
sub2s:
and byte ptr es:[bx],10001000b
or byte ptr es:[bx],00000101b
add bx,2
loop sub2s
pop es
pop cx
pop bx
ret
sub3:
push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,1
mov cx,2000
sub3s:
and byte ptr es:[bx],10001111b
or byte ptr es:[bx],00100000b
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
mov di,0
cld
mov cx,24
sub4s:
push cx
mov cx,160
rep movsb
pop cx
loop sub4s
mov cx,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
int9End:
nop
;编写7ch号中断程序
display:
jmp short dispalyStart ;占两个字节
db '1. Clear screen ',0
db '2. Set foreground color',0
db '3. Set background color',0
db '4. Scroll up one line ',0
dispalyStart:
push ax
push bx
push cx
push es
push di
mov cx,0
mov ax,0b800h
mov es,ax
mov di,160*8+60
mov bx,0
push cx
push di
s:
; push cx
; push di
mov ax,0
mov es,ax
mov cl,es:[bx+202h]
mov ch,0
jcxz s1
mov ax,0b800h
mov es,ax
mov es:[di],cl
inc di
mov byte ptr es:[di],4ah
inc di
inc bx
jmp short s
s1:
mov bp,sp
mov di,[bp]
mov cx,[bp+2]
inc cx
cmp cx,3
ja displayHere
mov ah,0
mov al,160
; mul cl
add di,ax
mov [bp],di
mov [bp+2],cx
inc bx
jmp short s
displayHere:
pop di
pop cx
pop di
pop es
pop cx
pop bx
pop ax
iret
displayEnd:
nop
;退回dos
code ends
end start
2.未解决的问题:
没有实现根据输入设定前景色和背景色,为了方便固定了,前景色设为紫色,背景色设为绿色。
3.可以改善的地方:
功能菜单显示,可以直接调用bios提供的中断来做更简洁,为了练习,这里使用了重写int7ch号中断来实现的,比较繁杂。
4.运行后效果如下:
4.1 功能界面:
4.2 --功能4 -- 按下数字键4,向上滚动一行
4.2 --功能2-- 设置前景色
4.3 -- 功能3--.设置背景色:
4.4 --功能1--清屏