在int9中断中如何使用call方式进行程序跳转

来源:互联网 发布:常见的网络诈骗手段 编辑:程序博客网 时间:2024/06/06 15:03

 

 

对于一个刚读完《王爽汇编语言》的初学者来说,在int9中断中使用call table[0] 这种方式进行跳转是个令人头痛的问题。

这个问题困恼了我许多天最后还是CSDN的朋友帮我解决了这个问题!该问题出现在 《王爽汇编语言》第16章的试验中。

 

 

 

 

 

问题如下:

这是一个16位dos程序,根据键盘输入(int9中断)来做相应的处理,以下代码能够正确运行,却无法实现需要的功能!

;jmp bx               需要用注释的这两种方式来运行程序,任意一种均可,已在代码中做好注释!
;call table[0]

 

 

 

cnzdgs的回答:

我想你目前遇到的障碍是由于把代码复制到了0:204H处而引起的。王爽发明的这种做法,如果单纯编程玩玩还可以,在实际应用中是不可取的,原因很简单,0:200H是中断向量表范围,不允许储存其它数据,驻留程序应该使用相应的DOS功能调用。
对于目前遇到的问题,是因为offset int9不等于204H,所以在int9程序中,所有用到偏移量(绝对地址)的地方都会出问题,简单的解决办法是在int9:前面加上org 204H,也可以用避免使用绝对地址的方式来解决,不过比较麻烦。

 

 

代码:

 

assume cs:code
code segment
org 204h
 int9:  ;自定义的int9中断例程
 jmp short init
 
 table_index db 2,3,4,5
 table dw sub3      ;226h,0 1,清空,2,设置前景,3,设置背景,4,屏幕向上滚动

init:
        push ax
        push bx
        push cx
        push es  
 push ds    
        in al,60h 
        pushf
        call dword ptr cs:[200h]
 mov bx,20h
 mov ds,bx
 mov bx,table[4]
 add bx,204h
 ;call sub3

;---------------------------------------------------------------------------
 ;jmp bx               需要用注释的这两个方式来运行程序,任意一种均可
 call table[0]
;---------------------------------------------------------------------------


 jmp int9ret
sub3:
 mov bx,0b800h
 mov es,bx
 mov bx,1
 mov cx,2000
 shl al,1
 shl al,1
 shl al,1
 shl al,1
sub3s:
 
 and byte ptr es:[bx],10001111b
 or es:[bx],al
 add bx,2
 loop sub3s
 ret
 

int9ret:
 pop ds
 pop es
        pop cx
        pop bx
        pop ax
        iret
int9end:
 nop

start:
        mov ax,cs
        mov ds,ax
        mov ax,0
        mov es,ax
        mov si,offset int9
        mov di,204h
        mov cx,offset int9end-offset int9
        cld
        rep movsb              ;安装自定义的int9中断例程       

         push es:[9*4]
        pop es:[200h]
        push es:[9*4+2]
        pop es:[202h]            ;保存原中断向量
         cli
        mov word ptr es:[9*4],204h
        mov word ptr es:[9*4+2],0h    ;设置自定义的中断向量
         sti
 mov ax,0b800h
        mov es,ax
        mov bx,0
        mov cx,2000
s:      mov byte ptr es:[bx],'A'
        add bx,2
        loop s
 
 mov cx,120
lp:     mov ah,0    ;进行120次读取BIOS键盘缓冲区的操作,
         int 16h   
        loop lp   
           
        mov ax,4c00h
        int 21h

code ends
end start

 

原创粉丝点击