Page 2 of 2

Re: inline assembly

Posted: Thu Jul 17, 2008 4:26 am
by lukem95
That looks very helpful Frank... rewriting that code was on my todo list anyway (i still have a few files in my OS that i didnt write from scratch, i'm rewriting them as i feel the need), so i guess it will just be placed at the top.

It seems so obvious now, thank you for explaining, i assumed that the EAX register would be saved as this is the default return register.. silly me =/

anyway, i'll rewrite my ISR routine when i get home, thanks again :)

Re: inline assembly

Posted: Sat Jul 19, 2008 5:37 pm
by lukem95
grrr :evil: still isnt working, can i run through my interpretation of this code? maybe i'm going wrong somewhere

Code: Select all

isr_common_stub:
   pusha                    ; Pushes all registers to stack

   mov ax, ds               ; puts data segment into AX
   push eax                 ; pushes AX to stack

   mov ax, 0x10  ; puts kernel data segment into AX
   mov ds, ax     ; sets all segments to kernel segment
   mov es, ax
   mov fs, ax
   mov gs, ax

   mov eax, esp  ; put stack pointer in eax
   push esp ; push stack pointer to stack (argument for isr_handler)

   call isr_handler

   pop eax       ; get rid of the default return value??

   pop eax        ; restore userland segment
   mov ds, ax    ; reassign this to the segment registers
   mov es, ax
   mov fs, ax
   mov gs, ax

   popa                     ; pop all registers (from stack pointer we modified)
   add esp, 8     ; do some cleaning up
   sti
   iret 
this all seems to make sense, but whatever i do i get an EAX value of 5, and even setting EBX doesn't have an effect... i've spent a long time debugging this but i'm having mental block... it must be something simple, but i cant think what would be ruining this routine

Re: inline assembly

Posted: Sat Jul 19, 2008 7:23 pm
by frank
Are you trying to set EAX by using inline assembly? That won't work because the isr stub restores all registers at the end before the IRET. You need to change the value of EAX by using

Code: Select all

registers->eax = value;
That edits the value of EAX on the stack so that when the ISR function returns the new value is poped into the EAX register.

Re: inline assembly

Posted: Sun Jul 20, 2008 5:00 am
by lukem95

Code: Select all

       __asm__ __volatile__ (" \
               push %1; \
               push %2; \
               push %3; \
               push %4; \
               push %5; \
               call *%6; \
               pop %%ebx; \
               pop %%ebx; \
               pop %%ebx; \
               pop %%ebx; \
               pop %%ebx; "
       : "=a" (ret)
       : "r" (regs->edi), "r" (regs->esi), "r" (regs->edx), "r" (regs->ecx), "r" (regs->ebx), "r" (func_addr));
       
       regs->eax = ret;
this is the code i'm using to test, with func_addr pointing to a function that simply returns 17, but eax has the value of 0x5

Re: inline assembly (well... syscalls) [SOLVED]

Posted: Sun Jul 20, 2008 4:00 pm
by lukem95
SOLVED!

i debugged a fair bit and got nowhere, so whilst playing with my code i decided to pass the memory location of the programs stack, and use a pointer to that. worked a charm.

thankyou to frank for the extensive help =D>