code segment
start: push cs
pop ds
mov ax,0
mov es,ax
mov di,0200h
mov si, offset setscreen
mov cx,offset setscreenend-offset setscreen
cld
rep movsb ;复制copy
mov word ptr es:[7ch*4],200h ;偏移地址
mov word ptr es:[7ch*4+2],0 ;段地址
mov ax,4c00h
int 21h
;伪指令,表示下一条指令从偏移地址200H开始,正好和安装后的偏移地址相同
;因为如果没有ORG 200H,此中断例程被安装以后,标号所代表的地址变了,和之前编译器编译有别
org 200h ;找了好久直到看到一篇博客,发现要加这个指令org 200h
setscreen:jmp 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
iret
sub1: push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,0
mov cx,2000 ; 25*80=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
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
setscreenend:nop
code ends
end start
这里我感觉,table 标号,若果没有加 org 200h,在安装中断例程后,table 段的内容是,cs:[偏移地址],而再复制这些指令的时候,是复制数据,此时table 标号就不能正确表达预想的位置。