Page 1 of 1

interrupt service routine for syscall with return value

Posted: Wed Jul 11, 2012 9:00 pm
by Dominator
In JamesM's kernel tutorials, he used the same assembly stub for interrupt service routines and syscalls. However, I guess the popa instruction will overwrite %eax, which holds the return value if a syscall has one (eg. pid_t fork()). As a result, the current implementation will return the system call number back, as it was stored in %eax, which seems useless. So I explicitly pushed and popped every general purpose register except for %eax when it comes to syscalls. Does that sound reasonable? At least now fork() works for me..

Code: Select all

pusha                    ; Pushes eax,ecx,edx,ebx,esp,ebp,esi,edi, in order
  ...
call isr_handler         ; Call into our C code.
  ...
popa                     ; Pops edi,esi,ebp...

Re: interrupt service routine for syscall with return value

Posted: Wed Jul 11, 2012 10:23 pm
by bluemoon
It depends on how you define your API.
Most people reassemble C convention, and simple write the "return value" on the pushed copy of registers on stack, so the popa restore the "new value" from stack.

Re: interrupt service routine for syscall with return value

Posted: Thu Jul 12, 2012 1:06 am
by qw
bluemoon wrote:... write the "return value" on the pushed copy of registers on stack, so the popa restore the "new value" from stack.
In fact this is very common for INT-based API's. DOS and the BIOS even modify the flags on the stack, to set or clear CF on error or success.

Re: interrupt service routine for syscall with return value

Posted: Thu Jul 12, 2012 11:50 am
by Jezze
There is no problem with using pusha/popa.

When you get to call isr_handler you push a pointer to the stack meaning you could have a struct containing everything pushed on to the stack which in the case of pusha would contain the eax register among others.

Code: Select all

void isr_handler(struct registers *regs)
{

    regs->eax = do_something();

}
When this function returns and you call popa the eax register will get the value you wanted.