Turbo C trouble with Interrupt Vector Table..

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Risc
Posts: 11
Joined: Sun Jun 14, 2009 8:29 pm

Turbo C trouble with Interrupt Vector Table..

Post by Risc »

Hello fellow OS developers!
My name is Risc and I'm new to these forums.

I am developing a small real mode kernel in Turbo C (v2 i think... the first 'blue' version) and have run into a problem.
This piece of code is driving me nuts. The INT_0 interrupt function is never called when I divide by zero. The system just hangs.

Code: Select all

void interrupt INT_0()
{
	printf("Interrupt 0\r\n");
}

void install_interrupts()
{	
	int int0 = (int)INT_0;
        /* I have tried with:
	int* int0 = (int*)INT_0; */
	
	/* Zero extra segment */
	asm xor ax, ax		 
	asm mov es, ax
	
	/* Intel-specific interrupts */
	asm mov dx, int0
	asm mov WORD [es:0x0], dx      /* Add the Interrupt procedure location to the IVT */
	asm mov WORD [es:0x02], cs	     /* Segment containing the procedure */
	asm sti
}
I would appreciate any input.
Thanks.

/Risc
User avatar
Troy Martin
Member
Member
Posts: 1686
Joined: Fri Apr 18, 2008 4:40 pm
Location: Langley, Vancouver, BC, Canada
Contact:

Re: Turbo C trouble with Interrupt Vector Table..

Post by Troy Martin »

Hmm, try adding push es before xor ax,ax and pop es after sti (and you don't really need sti in there.)

EDIT: Why does interrupt 0 return? And why don't you setup printf to make \n the same as \r\n?
Image
Image
Solar wrote:It keeps stunning me how friendly we - as a community - are towards people who start programming "their first OS" who don't even have a solid understanding of pointers, their compiler, or how a OS is structured.
I wish I could add more tex
User avatar
kop99
Member
Member
Posts: 120
Joined: Fri May 15, 2009 2:58 am

Re: Turbo C trouble with Interrupt Vector Table..

Post by kop99 »

Risc, if you have any bochs logs, then post that.
And do you load idtr?
So, post that code.
User avatar
Troy Martin
Member
Member
Posts: 1686
Joined: Fri Apr 18, 2008 4:40 pm
Location: Langley, Vancouver, BC, Canada
Contact:

Re: Turbo C trouble with Interrupt Vector Table..

Post by Troy Martin »

kop: the IDTR is pmode; Turbo C does crap in real mode.
Image
Image
Solar wrote:It keeps stunning me how friendly we - as a community - are towards people who start programming "their first OS" who don't even have a solid understanding of pointers, their compiler, or how a OS is structured.
I wish I could add more tex
Risc
Posts: 11
Joined: Sun Jun 14, 2009 8:29 pm

Re: Turbo C trouble with Interrupt Vector Table..

Post by Risc »

Troy Martin wrote:Hmm, try adding push es before xor ax,ax and pop es after sti (and you don't really need sti in there.)
Yes, I removed the boiler plate code for easier reading. That doesn't help unfortunately.
Troy Martin wrote:EDIT: Why does interrupt 0 return?
Borland C compilers have a special "interrupt" preprocessor tag you insert in front of function names to make the compiler push all registers, do whatever is inside of that function, pop all registers and finally iret.
It doesn't return in a normal fashion.
Troy Martin wrote:And why don't you setup printf to make \n the same as \r\n?
Maybe I will, when I get around this ;)
kop99 wrote:Risc, if you have any bochs logs, then post that.
And do you load idtr?
So, post that code.
Sorry but I don't use bochs (probably a stupid idea not to!). I've been trying out my kernel in VirtualBox, which is pretty worthless since I get no debugging capabilities. If anyone would like to elaborate on how to mount a floppy in bochs (I don't like rebuilding the image each time I recompile) I would be grateful.


EDIT: I strongly believe that the following lines are a cause of the problem.

Code: Select all

asm mov dx, int0
asm mov WORD [es:0x0], dx      /* Add the Interrupt procedure location to the IVT */
In pure assembler (NASM) I would have written:

Code: Select all

mov WORD [es:0x0], INT_0      /* Add the Interrupt procedure location to the IVT */
I don't know how to do that in TASM since it expects the second argument to be a register (note that int0 and INT_0 are two different things)...
ru2aqare
Member
Member
Posts: 342
Joined: Fri Jul 11, 2008 5:15 am
Location: Hungary

Re: Turbo C trouble with Interrupt Vector Table..

Post by ru2aqare »

Risc wrote: EDIT: I strongly believe that the following lines are a cause of the problem.

Code: Select all

asm mov dx, int0
asm mov WORD [es:0x0], dx      /* Add the Interrupt procedure location to the IVT */
In pure assembler (NASM) I would have written:

Code: Select all

mov WORD [es:0x0], INT_0      /* Add the Interrupt procedure location to the IVT */
I don't know how to do that in TASM since it expects the second argument to be a register (note that int0 and INT_0 are two different things)...
Try

Code: Select all

mov word ptr es:[0], offset INT_0
or even

Code: Select all

push cs
push offset INT_0
pop word ptr es:[0]
pop word ptr es:[2]
TASM and compatibles have the offset keyword (which NASM lacks unfortunately).
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Turbo C trouble with Interrupt Vector Table..

Post by jal »

Risc wrote:asm mov dx, int0
TC might well be assigning the address of int0 to dx.
I would appreciate any input.
It's rather simple to debug I would say. Print the address of the INT_0 routine, and what is found at 0000:0000 to see if they match.


JAL
User avatar
Troy Martin
Member
Member
Posts: 1686
Joined: Fri Apr 18, 2008 4:40 pm
Location: Langley, Vancouver, BC, Canada
Contact:

Re: Turbo C trouble with Interrupt Vector Table..

Post by Troy Martin »

Risc wrote:It doesn't return in a normal fashion.
It shouldn't return in any fashion; interrupt 0 is a divide error exception, meaning the return IP points to the offending address. That way, when it returns, it divides again, making it go "zOMG!" and fire exception 0 again.
Image
Image
Solar wrote:It keeps stunning me how friendly we - as a community - are towards people who start programming "their first OS" who don't even have a solid understanding of pointers, their compiler, or how a OS is structured.
I wish I could add more tex
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Re: Turbo C trouble with Interrupt Vector Table..

Post by earlz »

ru2aqare wrote:
Risc wrote: EDIT: I strongly believe that the following lines are a cause of the problem.

Code: Select all

asm mov dx, int0
asm mov WORD [es:0x0], dx      /* Add the Interrupt procedure location to the IVT */
In pure assembler (NASM) I would have written:

Code: Select all

mov WORD [es:0x0], INT_0      /* Add the Interrupt procedure location to the IVT */
I don't know how to do that in TASM since it expects the second argument to be a register (note that int0 and INT_0 are two different things)...
Try

Code: Select all

mov word ptr es:[0], offset INT_0
or even

Code: Select all

push cs
push offset INT_0
pop word ptr es:[0]
pop word ptr es:[2]


TASM and compatibles have the offset keyword (which NASM lacks unfortunately).
you could also try something like

Code: Select all

mov dx,word ptr [int0]
mov WORD [es:0x0], dx
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Re: Turbo C trouble with Interrupt Vector Table..

Post by mathematician »

Which Memory Model are you using?
The continuous image of a connected set is connected.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Turbo C trouble with Interrupt Vector Table..

Post by Combuster »

use getvect() and setvect(), turbo C has them for a reason.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Re: Turbo C trouble with Interrupt Vector Table..

Post by mathematician »

Combuster wrote:use getvect() and setvect(), turbo C has them for a reason.
Assuming that they don't call MS-DOS functions 35h (get vector) and 25h (set vector).
The continuous image of a connected set is connected.
Risc
Posts: 11
Joined: Sun Jun 14, 2009 8:29 pm

Re: Turbo C trouble with Interrupt Vector Table..

Post by Risc »

mathematician wrote:Assuming that they don't call MS-DOS functions 35h (get vector) and 25h (set vector).
It seems that they do unfortunately.

However, ru2aqare's code did the trick! It successfully traps to the correct function.
Now I seem to be having a stack problem or something because I can successfully do printc (print a character) but I can't printf (print a string). In Bochs it looks like printf never calls printc but sits around in an endless loop (remember, normally this works fine, it's just when calling it from the interrupt function). The interrupt function does nothing special btw.

Have a look at the code below:

Code: Select all

void printc(char c)
{
	asm push ax
	/* Print a character on screen */
	asm mov al, c
	asm mov ah, 0x0e
	asm int 0x10
	asm pop ax
}

/* Prints a string */
void printf(char* str)
{
	int i = 0;
	while(str[i] != '\0')
		printc(str[i++]);
}
...

Code: Select all

void interrupt INT_0()
{
	/* putc('a'); WORKS */
	printf("Hello world\0"); /* No cigar... */
	asm hlt
}
ru2aqare
Member
Member
Posts: 342
Joined: Fri Jul 11, 2008 5:15 am
Location: Hungary

Re: Turbo C trouble with Interrupt Vector Table..

Post by ru2aqare »

Code: Select all

void interrupt INT_0()
{
	/* putc('a'); WORKS */
	printf("Hello world\0"); /* No cigar... */
	asm hlt
}
[/quote]

I don't know what assembly code does your TC generate, but you may have to reload (and upon exit from the interrupt function, restore) the segment registers.
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Re: Turbo C trouble with Interrupt Vector Table..

Post by mathematician »

Risc wrote:
mathematician wrote:Assuming that they don't call MS-DOS functions 35h (get vector) and 25h (set vector).
It seems that they do unfortunately.

However, ru2aqare's code did the trick! It successfully traps to the correct function.
Now I seem to be having a stack problem or something because I can successfully do printc (print a character) but I can't printf (print a string). In Bochs it looks like printf never calls printc but sits around in an endless loop (remember, normally this works fine, it's just when calling it from the interrupt function). The interrupt function does nothing special btw.

Have a look at the code below:

Code: Select all

void printc(char c)
{
	asm push ax
	/* Print a character on screen */
	asm mov al, c
	asm mov ah, 0x0e
	asm int 0x10
	asm pop ax
}

/* Prints a string */
void printf(char* str)
{
	int i = 0;
	while(str[i] != '\0')
		printc(str[i++]);
}
...

Code: Select all

void interrupt INT_0()
{
	/* putc('a'); WORKS */
	printf("Hello world\0"); /* No cigar... */
	asm hlt
}
One thing I notice is that you are forgetting to zero the bh register. bh contains the video page number, and, unless you change it, it is page 0 which appears on the screen.
The continuous image of a connected set is connected.
Post Reply