1

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 ?

3
  • 1
    BOCHS's built-in debugger should be able to display / view it. But it sounds like you want to write code to search it. Normally for data accesses, you want to use DS or ES as the segment. Setting CS and then using loads/stores like cmp word ptr cs:[bx], 0 would be inconvenient, because you'd need code in that segment for CS:IP to still work. Commented Jun 18, 2021 at 13:17
  • 1
    XOR SI,SI,MOV DS,SI, LES AX,[SI], check if ES:AX is free, otherwise ADD SI,4 and repeat from LES. Commented Jun 18, 2021 at 14:25
  • What does it mean for an interrupt vector to be "free"? Do you mean you want to test whether the interrupt handler address is set to 0000:0000? Commented Jun 20, 2021 at 2:45

1 Answer 1

2

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
Sign up to request clarification or add additional context in comments.

13 Comments

Using lodsw for both loads looks like it's actually less convenient, and is costing an extra instruction. or ax, [si] / jz Found / inc si / inc si (4 bytes not counting the JZ) would do the same job as mov dx,ax/ lodsw / or ax,dx (5 bytes).
Or keep it simple with add si,2 for equal code-sizes but fewer instructions. (Of course, lodsw instead of inc/inc is even smaller, but costs another load so is worse for 8086 performance, if that's the goal instead of just code-size.)
My version is slower? Is code fetch + data access not the bottleneck on 8086 / 8088 for all of these, making smaller code in the loop the deciding factor? (For readability I like your mov / or version, though.)
Oh, you're using a cost model that doesn't include instruction-fetch. As I eventually found while researching Increasing Efficiency of binary -> gray code for 8086, a good method of estimating is count memory accesses and multiply by 4 to get a cycle count. mov taking only 2 cycles is relevant after a slow instruction like mul, to drain some bytes from the prefetch queue and make room for more code fetch to start to avoid unused memory cycles.
You really must time the code. Little else is going to be accurate. Certainly no more than the intuition of a good ASM programmer. Unfortunately, it’s never been simple. Abrams’s book has his “Zen Timer” implementation, which is very helpful for timing code sequences.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.