i just read an other question from 7 years ago... im trying to change the interruption of division by zero, so i wrote a function that will handle the division itself, but i cant understand why when setting the interruption i need to write i need to set es:[2] as cs, why is it 2 and not 4, and why cs and not ip, can someone explain this line? (MOV ES:[2], cs)
XOR ax, ax
mov ax, 0h
mov es, ax
mov es:[0], offset INT0h ; putting my function's ptr in the first int (for division by zero)
MOV ES:[2], cs ; Here I'm assuming segment of handler is current CS
; End of setup
mov ax, 15
mov cx, 0
div cx
mov ah, 0
int 16h
ret
INT0h PROC DivisionByZero
PRINT "ERROR: division by zero!"
IRET
INT0h ENDP DivisionByZero
In the real address mode, all of the 256 interrupt vectors are far pointers. A far pointer is composed of a 16-bit offset and a 16-bit segment value.
When we talk about a far pointer we first mention the segment and then followed by a colon we mention the offset. e.g. CS:IP
, DS:SI
Since x86 is a little endian architecture, when storing a far pointer in memory, we first store the least significant part which is the offset, followed by the most significant part which is the segment.
Because the DivisionByZero interrupt vector is the first on the interrupt vector table that starts at the very first address of memory, you'll find its far pointer at the addresses ranging from 0 to 3.
The offset goes to addresses 0 and 1.
The segment goes to addresses 2 and 3.