Reference the address of a function in assembly with c
Posted: Mon Jan 19, 2009 8:21 pm
Hello,
After coming from an ASM only world, I've decided to program an OS in c.
Currently I'm trying to get IDTs to work. After looking at the wiki, I have concluded that at least the initial structure of interrupt handlers must be written in assembly. So, I tried connecting my C code that builds up the IDT with my simple interrupt handler in assembly. Unfortunately apparently something is wrong with how I reference the function.
The OS simply locks up... I found that it can lock up *before* I call STI or LIDT, which is really strange. I guess it is caused by the way that I reference my interrupt handler.
The following is the code of the interrupt handler:
As I said, simple. I still haven't seen the "H" appear btw. I have a very similar function up for hardware except it also sends the EOI. The jmp is just an unneeded precaution.
Note btw that all hardware interrupts have been remapped and unmapped. This shouldn't matter though as lidt and sti aren't called yet.
Now for the IDT code:
..once again, the code for hardware interrupts is very similar.
Did anybody find any problems with my code? I particularly have found the code failing when setting offsets1 and 2. I don't know why. Am I referencing the functions correctly?
I am assembling the handler code and compiling the c code separately and then linking it all together. Is there anything wrong you can see that I have done?
Thank you,
Veniamin
After coming from an ASM only world, I've decided to program an OS in c.
Currently I'm trying to get IDTs to work. After looking at the wiki, I have concluded that at least the initial structure of interrupt handlers must be written in assembly. So, I tried connecting my C code that builds up the IDT with my simple interrupt handler in assembly. Unfortunately apparently something is wrong with how I reference the function.
The OS simply locks up... I found that it can lock up *before* I call STI or LIDT, which is really strange. I guess it is caused by the way that I reference my interrupt handler.
The following is the code of the interrupt handler:
Code: Select all
bits 32
global genericExceptionHandler
genericExceptionHandler:
mov byte [0xb8000], 'H'
cli
hlt
jmp $
Note btw that all hardware interrupts have been remapped and unmapped. This shouldn't matter though as lidt and sti aren't called yet.
Now for the IDT code:
Code: Select all
extern void genericExceptionHandler();
...
typedef unsigned char uint8;
typedef unsigned short uint16;
struct IDTDescr
{
uint16 offset_1; /* offset bits 0..15 */
uint16 selector; /* a code segment selector in GDT or LDT */
uint8 zero; /* unused, set to 0 */
uint8 type_attr; /* type and attributes, see below */
uint16 offset_2; /* offset bits 16..31 */
}__attribute__((packed));
...
struct idtPointer idtInfo;
struct IDTDescr *idtMem = (struct IDTDescr *) 0;
int numExceptions = 0x20;
int numHardware = 0x10;
int i;
idtInfo.idtLength = 8 * (numExceptions + numHardware) - 1;
idtInfo.idtStart = 0;
for(i = 0; i < numExceptions; i++)
{
idtMem->offset_1 = (int)&genericExceptionHandler & 0xFFFF; /* See below and above */
idtMem->offset_2 = (int)&genericExceptionHandler >> 16;
idtMem->selector = 8;
idtMem->zero = 0;
idtMem->type_attr = 0x8F;
idtMem++;
}
Did anybody find any problems with my code? I particularly have found the code failing when setting offsets1 and 2. I don't know why. Am I referencing the functions correctly?
I am assembling the handler code and compiling the c code separately and then linking it all together. Is there anything wrong you can see that I have done?
Thank you,
Veniamin