I want to display the interrupt vector table in my code in assembly 8086, then I want it to stop at the first free vector.
The question is : view the table of interrupt vectors and determine the first free vector.
I know that the address of the first vector of the table is 0000h, so I tried to set the cs
segment register to it and I couldn't do it? I tried: mov cs,0
and mov bx,0
mov cs,bx
but none worked.
Then I tried call cs:offset 0000h
and again it didn't work. So how can I do it ?
the question is : view the table of interrupt vectors and determine the first table free vector
This is a twofold question.
To display the numbers involved you can read Displaying numbers with DOS.
To find the first slot in the Interrupt Vector Table (IVT) that contains 0:0 you can use below code:
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
An IVT-slot that contains 0:0 is certainly free, but whether that is the first slot that is free is not necessarily true. Read more on this in @Margaret Bloom's answer in Find a free interrupt slot.
[EDIT]
A somewhat more elegant solution that is also shorter but slightly slower, and that clobbers one register less (the DX
register is not used):
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
And this is the idea that @Peter Cordes presented in a comment. It's 1 clock slower in the loop, but we can shave off 2 bytes if we replace the add si, 2
and sub si, 2
instructions by inc si
inc si
and dec si
dec si
:
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