interrupt service routine for syscall with return value

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
Dominator
Member
Member
Posts: 25
Joined: Fri Jul 06, 2012 10:52 am

interrupt service routine for syscall with return value

Post 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...
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: interrupt service routine for syscall with return value

Post 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.
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: interrupt service routine for syscall with return value

Post 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.
User avatar
Jezze
Member
Member
Posts: 395
Joined: Thu Jul 26, 2007 1:53 am
Libera.chat IRC: jfu
Contact:

Re: interrupt service routine for syscall with return value

Post 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.
Fudge - Simplicity, clarity and speed.
http://github.com/Jezze/fudge/
Post Reply