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.
I am trying to make my ring 3 application use a syscall to write to the screen. My ISR for the syscall (which is a trap) calls my screen writing function and it writes on the screen. This works. However, when I IRET from the syscall, I get a pagefault because the eip = 0x0. If I dump the stack while in the ISR it has the correct eip. When the IRET happens it is nowhere to be found.
I read in the AMD docs that when IRET to a lower privilage level a stack switch occurs. Does it switch stacks before getting the eip?
Why do you add '8' to esp before you leave the ISR? At the entry, you are pushing two bytes, '0' and '48', so you should rather add '2' to esp to discard them. I suspect you confused bytes and dwords here, two dwords would have a length of 8...
JoeKayzA wrote:
Why do you add '8' to esp before you leave the ISR? At the entry, you are pushing two bytes, '0' and '48', so you should rather add '2' to esp to discard them.
<alarm lights="red" siren="on">
beware... "push byte 12" doesn't tell the stack "advance stack pointer by one byte and store "12". It says "push value 12 on the stack and please encode the value as an immediate byte in the instruction stream because i don't need you to waste 32 bits here to store it".
</alarm>
The stack _always_ always grows and shrink by 32-bit value increments in protected mode. Check back your manuals or run the code in an emulator and compare esp before and after the two "push byte XX" commands and you'll see "add esp,8" is the proper thing to do...
and btw, it could have been written "add esp, byte 8" for the same reason
First, i would replace "pop esp" by "add esp,4" if i were you. I don't see any good reason to modify the stack pointer here unless you're trying to do stack-switching here ...
then, if the problem can be reproduced in the bochs, i suggest you break at "add esp,4", compare your stack with the stack when you enter the ISR and trace instructions untill (and past) you "IRET" ... that should give you more weapons to sneak the bug.
I wouldn't do this push/pop esp stuff around the call_irqhandler.
This is already done with INT/IRET - if you switch privilege levels, so it's kinda needless. You know, the esp/ss pair which is pushed on the stackupon INT, gets popped back upon IRET - and could be from a completely different task in case a task switch occurs.
Pype.Clicker wrote:
The stack _always_ always grows and shrink by 32-bit value increments in protected mode. Check back your manuals or run the code in an emulator and compare esp before and after the two "push byte XX" commands and you'll see "add esp,8" is the proper thing to do...
Strange, I never really noticed that, but you are right: Pushing a single byte doesn't work because there isn't even a 'pushb' instruction (in AT&T synthax) . So when you tell nasm that the operand size is one byte, it silently inserts a 'pushl' instruction instead. There is a seperate instruction for pushing and popping 16 bit words however, therefore it surprised me. OK, just learned another important detail!
then, if the problem can be reproduced in the bochs, i suggest you break at "add esp,4", compare your stack with the stack when you enter the ISR and trace instructions untill (and past) you "IRET" ... that should give you more weapons to sneak the bug.
I did this, and it turns out it was a bug in my application.. my kernel was working fine. :-\