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
