assume cs:code
code segment
start:
push cs
pop ds
mov ax,0
mov es,ax
mov si,offset setscreen
mov di,200h
mov cx,offset int7cend-offset setscreen
cld
rep movsb
cli
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0
sti
;以上 安装中断并设置中断向量
mov ax,4c00h
int 21h
setscreen:
jmp short set ;本条占2字节
table dw sub1+1D8H,sub2+1D8H,sub3+1D8H,sub4+1D8H ;编译器计算出的是相对地址,所以需要根据实际修正偏移。
set:
push bx
cmp ah,3
ja sret
mov bl,ah
mov bh,0
add bx,bx
;call word ptr table[bx] ;debug 发现table返回的值是 2A 而 sub1 实际的位置在 0000:0217
;理想情况下 table[bx] 指向 31行的第一个字单元,sub1返回的是 子程序sub1的入口偏移地址。
;现在问题 table[bx]指不到正确的位置,31行的 sub1返回的也不是正确的入口偏移.(暂时使用修正偏移的方法,希望以后找到更好的方法)
call word ptr table[bx+1d8H]
sret:
pop bx
iret
sub1: ;功能:全屏写空格,实现清屏
push bx
push cx
push es
push ax
mov bx,0b800h
mov es,bx
mov bx,0
mov ax,0ff20h
mov cx,2000
sub1s:
mov word ptr es:[bx],ax
add bx,2
loop sub1s
pop ax
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],11111000b
or es:[bx],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
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
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
int7cend:
nop
code ends
end start
调试这个程序感触颇多,十多分钟写好,调试了将近24小时。思路上完全正确。只是在偏移处因为自己了解的不够透彻才看不到问题所在,最后只要一步一步的debug才找到原因。遇到问题一定要深究,会对学过的知识有一个全新的认识。感谢:小甲鱼 等众多友人的帮助。