To give a more specific but still brief description of the problem: When I make any syscall from my C function - which itself is called from a userspace assembly procedure - the syscall returns to the C function, but then the C function doesn't return to the assembly procedure which called
it.
Here's the code segment which calls the C function:
Code:
welcome db "Welcome!",10,"This is a test", 0
extern entry_in_c
global userspace_entry
userspace_entry:
mov eax, 0
mov ebx, welcome
int 0x80
xchg bx, bx
call entry_in_c
jmp $
Here is the C function which is called:
Code:
void entry_in_c(void) {
asm("xchg %bx, %bx;\
mov $5, %eax;\
int $0x80;");
}
And finally, here's a very minimal example for my syscall ISR which causes the issue:
Code:
isr_syscall:
cli
sti
iret
As I step through the program to debug it in bochs, I monitor the stack. Here's what I notice:
At the beginning of the C function, the correct return address is at the top of the stack (happens to be 0x100755). So here, the stack looks like this:
(mem addr: value)
0x104ffb: 0x100755
The C function then pushed ebp (which here is 0) to the stack. It then saves esp into ebp.
0x104ff4: 0x0
0x104ffb: 0x100755
As soon as the C function calls int $0x80 (which is what I've chosen to be my syscall), four numbers are pushed to the stack:
0x104fec: 0x100764
0x104ff0: 0x1b
0x104ff4: 0x202
0x104ff8: 0x104ff4 <- this is equal to ebp... why?
...
The worrying part here is that this seems to have overwritten the 0x0 and the 0x100755 which were previously at the top of the stack. They're nowhere to be found on the stack whatsoever anymore, so, this is where I think it all went wrong.
When it returns to the C function it has popped the top two things from the stack, so the top now looks like this:
0x104ff4: 0x202
0x104ff8: 0x104ff4
And from there, it pops 0x202 into ebp (which is wrong), and then fatally, it returns to the address 0x104ff4, which is where the stack was at some point. From there, it just executed garbage memory and crashes.
So, any idea what's going on here? I'm not so familiar with using C functions with assembly, and have quite likely made a beginner's mistake here.
Thanks a lot