这个程序的难点时直接定址表的使用。课本上 table数据标号,在代码移入0000:0200位置后,就会由于编译器的原因,把table处理成一个我们不知道的位置,标号的参考基点的位置发生了变化。参考别人的代码,直接用cs:0202[bx]引用定址表,采用绝对地址。这样也很方便,很容易理解,不再使用 table 标号。
assume cs:code
code segment
main:
mov ax,cs
mov ds,ax
mov si,offset screen;传送的数据源
mov ax,0
mov es,ax
mov di,200h;传送的目标地址
cld;传送的方向
mov cx,offset scrend - offset screen
rep movsb
cli
mov ax,0;修改中断向量表
mov es,ax
mov word ptr es:[7ch * 4],200h
mov word ptr es:[7ch * 4 + 2],0
sti
mov ax,4c00h
int 21h
screen:
go:
jmp short scrcode
table dw offset clear0 - offset go + 200h
dw offset fclr1 - offset go + 200h
dw offset bclr2 - offset go + 200h
dw offset scrol3 - offset go + 200h
scrcode:
push bx
cmp ah,3
ja codend
mov bl,ah
add bl,bl
mov bh,0
call word ptr cs:202h[bx]
codend:
pop bx
iret
clear0:
push ax
push cx
push es
push di
mov ax,0b800h
mov es,ax
mov di,0;设置屏幕
mov cx,2000
clearlp:
mov byte ptr es:[di],32
add di,2
loop clearlp
pop di
pop es
pop cx
pop ax
ret
fclr1:
push bx
push cx
push es
push di
mov bx,0b800h
mov es,bx
mov di,1;设置屏幕es:di
mov cx,2000
fcollp:
mov bl,es:[di]
and bl,11111000b
add bl,al;新前景色属性
mov es:[di],bl
add di,2
loop fcollp
pop di
pop es
pop cx
pop bx
ret
bclr2:
push bx
push cx
push es
push di
mov cl,4
shl al,cl
mov bx,0b800h
mov es,bx
mov di,1;设置屏幕es:di
mov cx,2000
bcollp:
mov bl,es:[di]
and bl,10001111b
add bl,al;新前景色属性
mov es:[di],bl
add di,2
loop bcollp
pop di
pop es
pop cx
pop bx
ret
scrol3:
push bx
push cx
push es
push di
mov cx,0b800h
mov es,cx
mov di,0;屏幕
mov cx,1920
scllp:
mov bl, es:[di + 160]
mov es:[di],bl
add di,2
loop scllp
mov cx,80
spacelp:
mov byte ptr es:[di],' '
add di,2
loop spacelp
pop di
pop es
pop cx
pop bx
ret
scrend: nop
code ends
end main
下面是一个主程序
assume cs:code
code segment
main:
mov ah,3
mov al,5
int 7ch
mov ax,4c00h
int 21h
code ends
end main
效果如下:
谢谢阅读