利用直接定址表的中斷處理程序

字號:

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調(diào)用sub1。
    showfc:
     push ax
     push dx
     push bx
     push cx
    ;顯示功能提示
    showfc1:
     mov ah,9 ;int 21h 9號功能為在標準輸出上顯示以$結(jié)尾的字符串,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 ;輸入數(shù)字ASCII碼減30h轉(zhuǎn)換為十進制值。
     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 ;根據(jù)輸入的功能號碼來確定TABLE中子程序的偏移地址。
     call word ptr table[bx] ;調(diào)用子程序
     jmp short showfc1 ;功能循環(huán)
    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 ;顯存偶數(shù)地址為字符。
     mov cx,2000 ;顯存一頁4000字節(jié),偶數(shù)字節(jié)為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 ;顯存奇數(shù)地址為顏色值。
     mov cx,2000 ;顯存一頁4000字節(jié),奇數(shù)字節(jié)為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 ;列數(shù)還是要夠160的,這里是循環(huán)次數(shù),注意和上面的區(qū)別。
     rep movsb
     pop cx
     loop sub4s
     mov cx,80 ;一行160列,偶數(shù)列為80,偶數(shù)列也即是字符所在列。
     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