That GAS Assembly I wrote can be copied into a file and built by GCC (Create a file like KSysCall.S and gcc -o KSysCall.o -c KSysCall.S [Note: Capital S extension is preprocessed, lowercase S isn't]). Insert the
extern "C" declarations into a header and link KSysCall.o against the user space program.
In your kernel with the Interrupt Service Routine you'll have something along the lines:
Code: Select all
.global ISR
ISR:
pusha
push %ds
push %es
mov %ss, %eax
mov %eax, %ds
mov %eax, %es
call DoSysCall
pop %es
pop %ds
popa
iret
Code: Select all
struct UserSpaceRegisters
{
unsigned int EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX;
};
void DoSysCall(UINT32 ES, UINT32 DS, UserSpaceRegisters Regs)
{
/* Use Regs.EAX for the return value, the other values as whatever parameters the function takes */
switch(Regs.EAX)
{
case 1:
Regs.EAX = putint(Regs.EBX);
case 2:
Regs.EAX = SomeFunc(Regs.EBX, Regs.ECX);
default:
Regs.EAX = -1;
}
}
Note: I modified the earlier example to reflect this example, this is only an example though, it's been a while since I've played with ISRs so "some assembly required".