gcc and interrupts question

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.
Post Reply
proxy

gcc and interrupts question

Post by proxy »

ok, I have making an OS in C++ using gcc. So far i have gotten a basic heap, kernel threads, console input and output, and other stuff so i'mhappily moving along. I would like to have as much in C/C++ as possible so i am trying set my interrupt handlers in C/C++ as well. Here's my issue. gcc restores any pushes it does due to function calls JUST before the ret. so i can't simply call iret i need to restores the stack.

so my functions tend to look like this:

Code: Select all

void keyboard_handler(void) {
   __asm__ __volatile__("pusha");
   __asm__ __volatile__("push %ds");
   __asm__ __volatile__("push %es");
   __asm__ __volatile__("push %fs");
   __asm__ __volatile__("push %gs");

   
   outb(0x20, 0x20);
   
   // read a character
   g_Keyboard->readScancode();
   
   // bring the stack into a more sane state before putting things back
   // this is VERY compiler specific, we look at kernel.lst to see what this
   // should be...this would be much simpler if we had a frame pointer
   // but it is a small price to pay for speed ;)
   __asm__ __volatile__("add $0xc,%esp");
   
   __asm__ __volatile__("pop %gs");
   __asm__ __volatile__("pop %fs");
   __asm__ __volatile__("pop %es");
   __asm__ __volatile__("pop %ds");
   __asm__ __volatile__("popa");
   __asm__ __volatile__("iret");
}

as you can see i save as manyh registers as i can, and just before i restore, i "fix" the stack. I figure out how much to add by looking at my kernel.lst file generated by my make file (asm output interleaved with source) and look at how much gcc adjusted it.

this works just fine. but my question is this...is there a better way? somthing more generic (BTW i compile with -fomit-frame-pointer).

i'm alright with using this technique, but it's about as unportable as i can think of ;).

proxy
kaos

Re:gcc and interrupts question

Post by kaos »

You could write a stubs for the interrupt handlers in assembly and put them into a .asm or .s file. These handlers could save the registers, call the C routine, restore the registers, and do an iret. Is ~20 lines of assembly a big deal?

You could allow the hardware to save the registers by using interrupt gates.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:gcc and interrupts question

Post by Pype.Clicker »

another thing you could do is set a label in your first asm statement and inserting that label instead of the function name in your IDT ... so you'll be bypassing any code GCC could generate in a roughly more portable fashion ...

Also do keep in mind that -fomit-frame-pointer only omits the frame pointer if not necessary. If you have local variables, arguments or computations that make local temporary storage mandatory, the -fomit trick will not work any longer, so imho, your 'real work' will be held in a separate function anyway ...

you can also check this thread which had an interresting technique to overcome the problem of .S files by inlining the stub out of any C function ...
proxy

Re:gcc and interrupts question

Post by proxy »

thanks for the input, my issue is really that the adjustment i need to do is based on what work i do in the handler (in this case calling g_Keybaord->readScancode() which needs 3 dword pushes).

Anyway, this technique works and to be honest i wont be compiling with anything but gcc any time soon so it's not a big deal :)

proxy
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:gcc and interrupts question

Post by Pype.Clicker »

hmm. well, you're the one that make the final choice, but keep in mind that some things like these may even change from gcc 2.9x to gcc 3.x ...
Post Reply