汇编语言程序入口地址的直接定址表

(1)清屏;
(2)设置前景色;
(3)设置背景色;
(4)向上滚动一行。```````````````````````````````````````````````````````````````````````````````````````
(1)清屏:将显存中当前屏幕中的字符设为空格符;
(2)设置前景色:设置显存中当前屏幕中处于奇地址的属性字节的第0, 1, 2位;
(3)设置背景色:设置显存中当前屏幕中处于奇地址的属性字节的第4. 5, 6位:
(4)向上滚动一行:依次将第n+1行的内容复制到第n行处;最后一行为空。

我们将这4个功能分别写为4个子程序,请读者根据编程思想,自行读懂下面的程序。

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,2
      loop sub1s
      pop es
      pop cs
      pop bx
      ret

sub2: push bx
      push cx
      push es

      mov bx,0b800h
      mov es,bx
      mov bx,1
      mov cx,2000
sub2s:mov byte ptr es:[bx],' 11111000b'
      or es:[bx],al
      loop sub2s

      pop es
      pop cs
      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:mov byte ptr es:[bx],' 11111000b'
      or es:[bx],al
      add bx,2
      loop sub3s

      pop es
      pop cs
      pop bx
      ret

sub4: push cx
      push si
      push di
      push es
      push ds

      mov si,0b800h
      mov es,si
      mov ds,si
      mos si,160                      ;ds:si 指向第 n+1 行
      mov di,0                        ;ds:si 指向第 n 行
      cld
      mov cx,24                       ;共复制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 de
      pop es
      pop di  
      pop si
      pop cx
      ret

我们可以将这些功能子程序的入口地址存储在一个表中,它们在表中的位置和功能号相对应。对应关系为:功能号*2=对应的功能子程序在地址表中的偏移。程序如下:

setscreen: jmp short set

    table  dw sub1,sub2,sub3,sub4

      set: push bx

           cmp ah,3            ;判断功能号是否大于3
           ja,sret
           mov bl,ah
           mov bh,0
           add bx,bx        ;根据ah中的功能号计算对应子程序在table表中的偏移

           call word ptr table[bx]   ;调用对应的功能子程序

sret: pop bx
      ret

当然,我们也可以将子程序setscreen如下实现

setscreen: cmp ah,0
           je do1
           cmp ah,1
           je do2
           cmp ah,2
           je do3
           dmp ah,3
           je do4
           jmp short sret

do1: call sub1
     jmp short sret
do2: call sub2
     jmp short sret
do3: call sub3
     jmp short sret
do4: call sub4

sret: ret

显然,用通过比较功能号进行转移的方法,程序结构比较混乱,不利于功能的扩充。比如说,在setscreen中再加入一个功能,则需要修改程序的逻辑,加入新的比较、转移指令。
用根据功能号查找地址表的方法,程序的结构清晰,便于扩充。如果加入一个新的功能子程序,那么只需要在地址表中加入它的入口地址就可以了。


发布日期:

所属分类: 编程 标签:


没有相关文章!