我想在汇编8086中的代码中显示中断向量表,然后我希望它停止在第一个空闲向量
问题是:查看中断向量表并确定第一个空闲向量。
我知道表的第一个向量的地址是0000h,所以我试图将cs
段寄存器设置为它,但我做不到?我尝试过:mov cs,0
和mov bx,0
mov cs,bx
,但都不起作用
然后我尝试了call cs:offset 0000h
,但再次失败。那么我该怎么做呢?
问题是:查看中断向量表并确定第一个无表向量
这是一个双重问题。
要显示所涉及的数字,您可以阅读用DOS显示数字。
要在包含0:0的中断矢量表(IVT(中查找第一个插槽,可以使用以下代码:
xor si, si ; Set DS:SI to the start of the IVT
mov ds, si
cld ; Have LODSW increment (by 2) the SI register
Again:
lodsw ; The offset part of a vector
mov dx, ax
lodsw ; The segment part of a vector
or ax, dx
jz Found ; If both parts are zero, then their OR will set ZF=1 (Zero Flag)
cmp si, 1024
jb Again ; Repeat until the end of the IVT which is at address 1024
NotFound:
...
jmp ..
Found:
sub si, 4 ; -> DS:SI is the address of the first slot containing 0:0
包含0:0的IVT槽当然是空闲的,但这是否是第一个空闲的槽并不一定是真的。请阅读@Margaret Bloom在"寻找免费中断时段"中的回答。
[编辑]
一个稍微更优雅的解决方案,它也更短但稍微慢一点,并且减少了一个寄存器(不使用DX
寄存器(:
xor si, si ; Set DS:SI to the start of the IVT
mov ds, si
Again:
mov ax, [si] ; The offset part of a vector
or ax, [si+2]; The segment part of a vector
jz Found ; If both parts are zero, then their OR will set ZF=1 (Zero Flag)
add si, 4
cmp si, 1024
jb Again ; Repeat until the end of the IVT which is at address 1024
NotFound:
...
jmp ..
Found:
; -> DS:SI is the address of the first slot containing 0:0
这就是@Peter Cordes在评论中提出的想法。循环中慢了1个时钟,但如果我们用inc si
inc si
和dec si
dec si
:替换add si, 2
和sub si, 2
指令,我们可以减少2个字节
xor si, si ; Set DS:SI to the start of the IVT
mov ds, si
cld
Again:
lodsw ; The offset part of a vector
or ax, [si] ; The segment part of a vector
jz Found ; If both parts are zero, then their OR will set ZF=1 (Zero Flag)
add si, 2
cmp si, 1024
jb Again ; Repeat until the end of the IVT which is at address 1024
NotFound:
...
jmp ..
Found:
sub si, 2 ; -> DS:SI is the address of the first slot containing 0:0