Search code examples
assemblyx86-16emu8086

How to display the interrupt vector table in assembly 8086?


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 ?


Solution

  • 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