王爽《汇编语言》第十六章的实验,我做了一些改动。














































































































mov ah,bh
mov bl,ah
mov bh,0
add bx,bx ;根据输入的功能号码来确定TABLE中子程序的偏移地址。
call word ptr table[bx] ;调用子程序
jmp short showfc1 ;功能循环

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 ;显存偶数地址为字符。
mov cx,2000 ;显存一页4000字节,偶数字节为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 ;显存奇数地址为颜色值。
mov cx,2000 ;显存一页4000字节,奇数字节为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 ;列数还是要够160的,这里是循环次数,注意和上面的区别。
rep movsb
pop cx
loop sub4s

mov cx,80 ;一行160列,偶数列为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

codesg ends
end start
































































































唉,做个这么简单的东西都要花这么长时间,年轻人的话估计有45分钟也就搞定调试完了。