|
5鱼币
答案有两种方式 附上代码
第一种方法代码:
assume cs:code
code segment
;新的int 7ch中断例程
s: jmp short set
table dw sub1,sub2,sub3,sub4
set: push bx
cmp ah,3 ;判断ah中的功能号是否大于3
ja sret
mov bl,ah
mov bh,0
add bx,bx ;计算对应子程序在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
subles: mov byte ptr es:[bx],' '
add bx,2
loop subles
pop es
pop cx
pop bx
ret
;设置前景色,al传送颜色值,(al)∈{0,1,2,3,4,5,6,7}
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
;设置背景色,al传送颜色值,(al)∈{0,1,2,3,4,5,6,7}
sub3: push ax
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
pop ax
ret
;向上滚动一行
sub4: push cx
push si
push di
push es
push ds
mov si,0b800h
mov es,si
mov ds,si
mov si,160 ;ds:si指向第N+1行
mov di,0 ;es:di指向第N行
cld
mov cx,24 ;共复制24行
sub4s: push cx
mov cx,160
rep movsb ;复制
pop cx
loop sub4s
mov cx,80
sub4s1: mov byte ptr [160*24+si],' ' ;最后一行清空
add bx,2
loop sub4s1
pop ds
pop es
pop di
pop si
pop cx
ret
send: nop
start: mov ax,cs
mov ds,ax
mov si,offset s ;设置ds:si指向源地址
mov ax,0
mov es,ax
mov di,200h ;设置es:di指向目标地址
mov cx,offset send-offset s ;设置cx为传输长度
cld ;设置传输方向为正
rep movsb
;在中断向量表中设置新的int 7ch中断例程的入口地址
cli ;设置IF=0屏蔽中断
mov word ptr es:[7ch*4],0
mov word ptr es:[7ch*4+2],20h
sti ;设置IF=1不屏蔽中断
;结束
mov ax,4c00h
int 21h
code ends
end start
我自己改的代码:
assume cs:code
code segment
;新的int 7ch中断例程
s: jmp short set
table dw sub1,sub2,sub3,sub4 ;这里对应的是你这里的代码的偏移地址,但是到了table【bx】中cs当前是0 ,也就是少加了200的偏移地址。可以通过在写偏移变成0短地址写成20h
set: push bx
cmp ah,3 ;判断ah中的功能号是否大于3
ja sret
mov bl,ah
mov bh,0
add bx,bx ;计算对应子程序在table表中的偏移
add bx,2
call word ptr ss:[bx] ;调用对应的功能子程序
sret: pop bx
iret
;功能:清屏
sub1: push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,0
mov cx,2000
subles: mov byte ptr es:[bx],' '
add bx,2
loop subles
pop es
pop cx
pop bx
ret
;设置前景色,al传送颜色值,(al)∈{0,1,2,3,4,5,6,7}
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
;设置背景色,al传送颜色值,(al)∈{0,1,2,3,4,5,6,7}
sub3: push ax
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
pop ax
ret
;向上滚动一行
sub4: push cx
push si
push di
push es
push ds
mov si,0b800h
mov es,si
mov ds,si
mov si,160 ;ds:si指向第N+1行
mov di,0 ;es:di指向第N行
cld
mov cx,24 ;共复制24行
sub4s: push cx
mov cx,160
rep movsb ;复制
pop cx
loop sub4s
mov cx,80
sub4s1: mov byte ptr [160*24+si],' ' ;最后一行清空
add bx,2
loop sub4s1
pop ds
pop es
pop di
pop si
pop cx
ret
send: nop
start: mov ax,cs
mov ds,ax
mov si,offset s ;设置ds:si指向源地址
mov ax,20h
mov ss,ax
mov di,200h ;设置es:di指向目标地址
mov cx,offset send-offset s ;设置cx为传输长度
cld ;设置传输方向为正
mov ax,0
rep movsb
;在中断向量表中设置新的int 7ch中断例程的入口地址
cli ;设置IF=0屏蔽中断
mov word ptr es:[7ch*4],200h ;偏移地址位
mov word ptr es:[7ch*4+2],0h ;段地址位
sti ;设置IF=1不屏蔽中断
;结束
mov ax,4c00h
int 21h
code ends
end start
问题一: 第一种方式正常运行,将int7ch的段地址设置为20h,运行完这个程序,运行其他程序触发了int7ch中断,那时候段地址是不是20h?
要是是的话,我自己把ss的值设置为20h,把int7ch中断的段地址写为0,这样写跳转地址的时候写ss:【bx】这样跟第一种方法定位是一 样的效果,为什么 我没有成功运行。
问题二:
我个人感觉第一个正常的代码有问题,table【bx】,这应该是cs:【bx】,也就是之前在int7ch中断地址段地址写的是20h所以应该就是 20:【0】,但是这个地址的代码是jmp short set 占两个字节,所以 sub1的地址应该是 20:【2】,才对为什么是这种情况,还有就是 即使第二个方式 没有多加这两个字节 也是不能成功运行的。
求大神赐教赐教!!!!!!! |
|