分享
 
 
 

用汇编编写DOS下的内存驻留程序(3)

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

三 中断矢量

3.1 IBM PC提供的中断

IBM PC有两种基本形态的中断.如果是由外围设备所产生的中断就叫做硬件中断(Hardware interrupt),譬如:键盘,磁盘机和时钟等外围设备都可以产生硬件中断.外围设备所产生的中断信号都连接到中断控制器,中断控制器可以根据它们之间的重要性来安排优先顺序,以便使CPU有效地处理这些硬件信号.另一种中断是软件中断(Software interrupt),软件中断也叫做陷井(Trap),它是由执行中的软件所产生.虽然软件包中断的处理方式和硬件中断完全相同,但是通常软件中断是希望执行操作系统所提供的服务.

表3.1是IBM PC所提供的中断,这些中断是根据中断号码和中断矢量(Interrupt vector)排列.

IBM PC的用户或是编写应用程序的程序人员很少会直接接触到硬件中断,除非是使用某些特殊的硬件,或是需要较严格的要求时,最常被修改的硬件中断是敲键盘所产生的中断(9H),尤其是文本编辑的程序.大体而言,只有硬件设计者基是系统程序人员才会注意到所有在硬件中断;编写内存驻留程序的设计人员则只使用到部分硬件中断而已,尤其是:键盘中断和计时器(Timer)的中断.

反之,软件中断对于任何编写汇编程序的人,甚至对编写高级语言程序的人都相当的重要.软件中断是应用程序进入到IBM PC操作系统的接口,经由这些接口应用程序才可以执行所要求的系统服务.

其中软件中断中最重要,同时也是最常被汇编语言程序设计师所用到是DOS INT 21H.这个中断是执行DOS系统调用的软件中断,它可以让应用程序执行任何DOS的操作.

接下来最有用的软件中断是ROM-BIOS(基本输入输出系统)所提供的中断.这些软件中断是IBM PC所提供的的低层次服务,譬如:键盘输入,显示器输出和磁盘机的输入与输出等.

3.2 键盘输入的方法

以下就以IBM PC从键盘读取字符为例子,来说明中断的工作方式.IBM PC从键盘读取字符时,使用了两种不同形式中断,亦即:硬件中断和软件中断.当使用者从键盘敲下一个键时,键盘的线路就会送出一个信号.这个信号会造成硬件中断发生,从而触发低层次的键盘中断处理程序开始执行.这个中断处理程序马上从键盘的硬件读取使用者所敲入的字符,然后把它放到一个队列中,如果这个队列填满时,键盘中断处理程序会使IBM PC发出一声响.键盘中断处理程序做完这些事情之后,它就把控制权交还给原先被中断的程序.如果有一个程序希望从键盘读取一个字符时,它就发出适当的软件中断信号,这时候就由相对应的中断处理程序去检查键盘队列,并且传回队列中的第一个字符.

上面所介绍的键盘输入工作方式,在中断驱动系统中很普遍地采用.这和做法可以把实际上需要输入的应用程序和实际上执行输入的处理部分分开来.这种做法也可以用在其它不同形式的输入和输出外围设备.

3.3 改变输入矢量

中断矢量储存在IBM PC最前面的400H个字节中.每一个矢量的长度是四个字节组成,这四个字节内所存放的是中断处理程序执行的地址值.其中前两个字节包含地址值的位移(Offset)部分,后面的两个字节则包含了段(Segment)部分.

中断矢量有两种修改方法.可以直接地设置中断矢量的地址值,或是使用DOS所提供的系统调用设置中断矢量的地址值.

3.3.1 直接设置中断矢量

因为中断矢量只是存放地址值的存储位置,因此我们可以直接地把地址存放到存储位置中.以下是一个小例子:

mov ax,0

mov es,ax

mov word ptr es:24,offset Keyboard

mov word ptr es:26,seg Keyboard

在许多情况下,上面的程序都可以正确地执行.但是如果上面的程序正在执行时突然敲下一个键的话,就可能会问题;而最糟的情 况是发生:第三个MOV已经执行完毕,而第四个MOV尚未执行时.如果在此时敲下任何键的话,键盘中断矢量都没有任何意义,而造成整个系 统死机.因此我们可以在设置中断矢量时,让中断无效,譬如:

mov ax,0

mov es,ax

cli

mov word ptr es:24,offset Keyboard

mov word ptr es:26,seg Keyboard

上面的做法在大部分的情况下都可以正确地执行.但是CLI这个指令无法停止NMI中断(不可屏蔽中断),因此如果发生NMI中断时就 没用办法.下面的这一种做法虽然比较复杂,但是对于所有的中断都有效,这包括了NMI中断在内:

mov word ptr kbd-ptr[0],offset Keyboard

mov word ptr kbd-ptr[2],seg Keyboard

mov di,0 ;Use Di to Set ES to zero

mov es,di ;Set ES to destination segment

mov di,24 ;Set DI to destination offset

mov si,offset kbdptr ;set SI to source offset

mov cx,2 ;Set word count to 2

cld ;Set direction to forward

cli ;Disable interrupts

rep movsw ;Copy the new vector

sti ;Enable interrupts

kbdptr dd ?

上面的程序中,kbdptr是两个字节(WORD)的指针(Pointer),其中包含了键盘 中断处理程序的起始志趣值.REP这个指令将根据寄存 器CX所设置的次数来重复执行MOVSW,而整个指令就如同单一的指令一样.NMI中断不能够发生在一个完整的指令中.因为地址值搬移的操 作都能包含在一个单一指令中,因此可以免除任何中断的干扰.

3.3.2 使用DOS来设置中断矢量

因为要想安全地设置中断矢量需要一些技巧,因此DOS提供了一项特殊的服务,以帮助程序人员安全地设置中断矢量,如果只使用 DOS所提供的这项服务来设定中断矢量的话,那么就不必担心会发生前面所叙述的差错.DOS同时也提供了:读取中断矢量的服务.因为读 取中断矢量的内容不会修改系统的状态;因此若直接写程序读取,也很安全.但是如果你要自己直接读取中断矢量的内容时,就必须计算 出中断矢量的位置.而DOS已经提供了这项服务.

使用DOS所提供的系统调用,来读取中断矢量的内容时,必须利用INT 21H中的函数35H(读取中断矢量),这个函数热气矢量号码来 计算中断矢量的地址,然后返回其中的内容.以下就是一个例子:

Old_Keyboard_IO dd ?

mov al,16h

mov ah,35h

int 21h

mov word ptr Old_Keyboard_IO,bx ;Offset of interrupt handler

mov word ptr Old_Keyboard_IO,es ;Segment of interrupt handler

用DOS来设置中断矢量例子:

New_Keyboard_IO dd ?

mov word ptr New_Keyboard_IO,bx ;Offset of interrupt handler

mov word ptr New_Keyboard_IO,es ;Segment of interrupt handler

mov al,16h

mov ah,25h

int 21h

3.4 检查中断矢量

这里都是采用COM格式编程,可以建立一个BAT文件来处理写好的程序,以减少击键次数.设BAT文件名为MAKE.BAT:

MASM %1

LINK %1

EXE2BIN %1.EXE %1.COM

如果写好的程序名为MACRO.ASM,则可敲入:

C:\MAKE MACRO.ASM

即可.

3.5 显示中断矢量

下面这个例子可以列出所有的重要的中断矢量内容,在刚刚打开PC时,并且没有执行任何驻留程序时,可以发现所有的中断矢量段值都相同,这些地址值所存放的是ROM的程序.当你修改中断矢量之后,就可以利用这个程序观察到中断矢量的变化.以下就是IVEC.ASM的内容:

cseg segment para public 'CODE'

org 100h

jmp start

assume cs:cseg,ds:cseg

start:

mov bx,cs ;Make data seg be the same as

mov ds,bx ;the code seg

call vectors

waitIn:

mov ah,0bh

int 21h

cmp al,0ffh

jne waitIn

mov ah,4ch

int 21h

;****************************************************************************

;Scan through display table,prinying two vectors per line

;If any record has an interrupt #=zero,this indicates

;end of the table.

;****************************************************************************

mov di,offset disptab ;Pointer to start of table

mov dh,0 ;Zero out top half of DX

vloop:

mov dl,[di] ;Get the interrupt number

cmp dl,0 ;If it's zero,we are done

je vdone ;so exit loop

add di,1 ;Advance pointer 1 byte

mov si,[di] ;Get pointer to description

call dvector ;Call the display routine

add di,2 ;Get the interrupt number

mov dl,[di] ;Advance to the next record

cmp dl,0 ;If it's zero,we are done

je vdone ;so exit loop

add di,1 ;Advance pointer 1 byte

mov si,[di] ;get pointer to description

call dvector ;Call the display routine

add di,2 ;Advance to the next record

jmp vloop

vdone: ;Print final CRLF

ret

vectors endp

;----------------------------------------------------------------------------

;Displays an interrupt vector.Display is in the form of

;<banner>,<interrupt#>,<seg>:<offset>

;where <interrupt #>,<seg>and<offset>

;are all dexadecimal numbers

;Call with

;DX -interrupt number

;DS:SI -pointer to banner string

;----------------------------------------------------------------------------

dvector proc near

call dstring ;Display the string in DS:SI

call dbyte ;Display the byte in DL

call dspace ;Display a space

call dspace

;

mov al,dl ;move the interrupt number to AL

mov ah,35h ;Function is Get interrupt vector

int 21h

mov dx,bx ;Move BX to DX so we can display

call ddword ;double-word in ES:DX

call dEndFra

call dcrlf ;Display a newline

ret

dvector endp

;----------------------------------------------------------------------------

;DS:SI points to ASCII string to be printed

;----------------------------------------------------------------------------

dstring proc near

push si

push ax

dis: mov al,[si] ;Fetch the next character

cmp al,0 ;If it's zero,we are done

je disdone

call dchar ;If not,point it

inc si ;Advance pointer to nest char

jmp dis

disdone:pop ax

pop si

ret

dstring endp

;----------------------------------------------------------------------------

;ES:DX contains double word to be displayed

;----------------------------------------------------------------------------

ddword proc near

push dx ;Save offset temporarily

mov dx,es ;Move segment to DX

call dsword ;Display segment

call dcolon ;Print a ";"

; call dcrlf

pop dx ;Restore offset to DX

call dsword ;Display offset

ret

ddword endp

;----------------------------------------------------------------------------

;DX containes single word to be displayed

;----------------------------------------------------------------------------

dsword proc near

push dx ;Save low byte temporarily

mov dl,dh ;Move high byte to low byte

call dbyte ;Display high byte

pop dx ;Restore low byte to DL

call dbyte ;Display low byte

ret

dsword endp

;----------------------------------------------------------------------------

;DL contains byte to be displayed

;----------------------------------------------------------------------------

dbyte proc near

push ax ;Save any registers used

push dx

push si

push dx ;Save low nybble temporarily

push cx ;Save CX

mov cl,4 ;Set shift count to 4

shr dx,cl ;Shift high nybble into low nybble

and dx,0fh ;Mask out all but low nybble

mov si,dx ;Use low nybble as index into

mov al,hextab[si] ;hexadecimal character table

call dchar ;Display character

pop cx ;Restore CX

pop dx ;Restore low nybble

and dx,0fh ;Mask out all but low nybble

mov si,dx ;Use low nybble as an index into

mov al,hextab[si] ;hexadecimal character table

call dchar ;Display character

pop si ;Restore registers

pop dx

pop ax

ret

dbyte endp

;----------------------------------------------------------------------------

;Display a ":"

;----------------------------------------------------------------------------

dcolon proc near

mov al,':'

call dchar

ret

dcolon endp

;----------------------------------------------------------------------------

;Display a " "

;----------------------------------------------------------------------------

dspace proc near

mov al,' '

call dchar

ret

dspace endp

;----------------------------------------------------------------------------

;Display a Carriage Return/Line Feed

;----------------------------------------------------------------------------

dcrlf proc near

mov al,0dh

call dchar

mov al,0ah

call dchar

ret

dcrlf endp

;----------------------------------------------------------------------------

;Display the character contained in AL

;----------------------------------------------------------------------------

dchar proc near

push ax

push bx

mov bh,1

mov ah,0eh

int 10h

pop bx

pop ax

ret

dchar endp

;----------------------------------------------------------------------------

;Data define

;----------------------------------------------------------------------------

hextab db '0123456789ABCDEF',0

disptab db 05h ;Print screen

dw v05

db 19h ;Bootstrap loader

dw v19

db 08h ;Timer tick

dw v08

db 1ah ;Real_time clock

dw v1a

db 09h ;Keyboard input

dw v09

db 1bh ;CTRL_Break handler

dw v1b

db 0bh ;Comm.port 1

dw v0b

db 1ch ;Timer control

dw v1c

db 0ch ;Comm.port 0

dw v0c

db 1dh ;Pointer to video parameter table

dw v1d

db 0dh ;Hard disk controller

dw v0d

db 1eh ;Pointer to disk parameter table

dw v1e

db 0eh ;Floppy disk controller

dw v0e

db 1fh ;Pointer graphics character table

dw v1f

db 0fh ;Printer controller

dw v0f

db 20h ;Program terminate

dw v20

db 10h ;Video driver

dw v10

db 21h ;DOS universal function

dw v21

db 11h ;Equipment check

dw v11

db 22h ;Pointer to termination handler

dw v22

db 12h ;Memorey size check

dw v12

db 23h ;Pointer to Ctrl_C handler

dw v23

db 13h ;Disk driver

dw v13

db 24h ;Pointer to critical error handler

dw v24

db 14h ;Communications driver

dw v14

db 25h ;Absolute disk read

dw v25

db 15h ;Cassette driver

dw v15

db 26h ;Absolute disk write

dw v26

db 16h ;Keyboard driver

dw v16

db 27h ;Terminate and stay resident

dw v27

db 17h ;Printer driver

dw v17

db 2fh ;Print spooler

dw v2f

db 18h ;Rom basic

dw v18

db 0

dw 0

v05 db 186,5 dup (20h),'Print screen:',26 dup (20h),0

v08 db 186,5 dup (20h),'Timer tick controller:',17 dup (20h),0

v09 db 186,5 dup (20h),'Keyboard input:',24 dup (20h),0

v0b db 186,5 dup (20h),'Communication port 1:',18 dup (20h),0

v0c db 186,5 dup (20h),'Communication port 0:',18 dup (20h),0

v0d db 186,5 dup (20h),'Hard disk controller:',18 dup (20h),0

v0e db 186,5 dup (20h),'Floppy disk controller:',16 dup (20h),0

v0f db 186,5 dup (20h),'Printer controller:',20 dup (20h),0

v10 db 186,5 dup (20h),'Video driver:',26 dup (20h),0

v11 db 186,5 dup (20h),'Equipment check:',23 dup (20h),0

v12 db 186,5 dup (20h),'Memory size check:',21 dup (20h),0

v13 db 186,5 dup (20h),'Disk driver:',27 dup (20h),0

v14 db 186,5 dup (20h),'Communication driver:',18 dup (20h),0

v15 db 186,5 dup (20h),'Cassette driver:',23 dup (20h),0

v16 db 186,5 dup (20h),'Keyboard driver:',23 dup (20h),0

v17 db 186,5 dup (20h),'Printer driver:',24 dup (20h),0

v18 db 186,5 dup (20h),'ROM BASIC:',29 dup (20h),0

v19 db 186,5 dup (20h),'Bootstrap loader:',22 dup (20h),0

v1a db 186,5 dup (20h),'Real_time clock:',23 dup (20h),0

v1b db 186,5 dup (20h),'Ctrl_break handler:',20 dup (20h),0

v1c db 186,5 dup (20h),'Timer control:',25 dup (20h),0

v1d db 186,5 dup (20h),'Video parameter table:',17 dup (20h),0

v1e db 186,5 dup (20h),'Disk parameter:',24 dup (20h),0

v1f db 186,5 dup (20h),'Graphic character table:',15 dup (20h),0

v20 db 186,5 dup (20h),'Programe terminate:',20 dup (20h),0

v21 db 186,5 dup (20h),'DOS universal function:',16 dup (20h),0

v22 db 186,5 dup (20h),'Terminate vector:',22 dup (20h),0

v23 db 186,5 dup (20h),'Ctrl_C vector:',25 dup (20h),0

v24 db 186,5 dup (20h),'Critical error vector:',17 dup (20h),0

v25 db 186,5 dup (20h),'Absolute disk read:',20 dup (20h),0

v26 db 186,5 dup (20h),'Absolute disk write:',19 dup (20h),0

v27 db 186,5 dup (20h),'Terminate and stay resident:',11 dup (20h),0

v2f db 186,5 dup (20h),'Print spooler:',25 dup (20h),0

cseg ends

end start

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有