I’m trying to re-program instruction vector table. Here is the code I use:
#include <stdio.h>
int a=1;
void func();
void keyboard()
{
printf("\n\nkeyboard!!!\n");
a=0;
asm{iret}
}
int main ()
{
printf("starting...");
func();
return 0;
}
int vectorcs = 0;
int vectorip = 0;
void func()
{
printf("\n*****\n");
asm{
cli
mov ax,0
mov es,ax
mov bx,36
mov ax,word ptr es:[bx]
mov vectorip,ax
push ax
mov ax,word ptr es:[bx+2]
mov vectorcs,ax
push ax
mov ax,cs
mov word ptr es:[bx],offset keyboard
mov es:[bx+2],ax
sti
}
printf("\n%d %d\n",vectorip,vectorcs);
while (a) {
}
asm {
cli
mov es,bx
mov bx,36
pop ax
mov word ptr es:[bx+2],ax
}
asm{
pop ax
mov word ptr es:[bx],ax
sti
}
}
I’m using Turbo C++ 3.0
When I try to run this program, “16 Bit MS-DOS Subsystem: The NTVDM CPU has encountered an illegal instruction.” appears. Then it shows contents of CS, OP, and IP registers. I can’t continue the program. Any suggestions?
What you’re doing is not right for multiple reasons:
interruptkeyword. And they’ll haveiretfor you at the end.volatile, otherwise you’re risking to have accesses to them incorrectly optimized out by the compiler.asmblocks mess with the stack pointer. The first block exits with several extra words on the stack. This may be completely unexpected for the compiler and can break your program. There may be other issues, but I’m not going to check with the compiler documentation which registers must be preserved by inline assembly blocks. I’d avoid doing this altogether and opt for thesetvect()function instead.InDosflag variable and still, not all are safe to call whenInDos=0.See how to change interrupt vectors, define interrupt service routines and call DOS functions from them, all with Turbo C, in the answer to this question.
You may also find this question and its answers useful.
EDIT:
This is how you do it without dos.h’s functionality with inline asm: