Page 1 of 1
inline asm (DJGPP)
Posted: Tue Aug 03, 2004 6:01 am
by Eric
I thought that it would be nice to print all the CPU registers / EIP and so on when when an exception occurs. I suppose the EIP is on the stack, but how do I pop it in inline asm and Store it in a variabel (in a c fuction). Also need help to read the eax, ebx and store the values.
Re:inline asm (DJGPP)
Posted: Tue Aug 03, 2004 6:54 am
by Pype.Clicker
I suggest you get a look at
http://www.osdev.org/osfaq2/index.php/H ... crashed%21. It's not mandatory to 'pop' the information you want to display: you just need to take a pointer towards the stack structure where register content stands.
Code: Select all
exc_handler:
;; your 'normal' handler comes here
pushad
push ds
push es
mov ax,KERNEL_DATA_SELECTOR
mov ds,ax
mov es,ax
push esp ;; this is the parameter for gpfExcHandler ;)
call gpfExcHandler
add esp,4
pop es
pop ds
popad
iret
and when executed, gpfExcHandler will receive the pointer to the faulty state as
Code: Select all
struct exc_status {
dword es, ds;
dword regs[8]; // eax, ecx, edx, ebx and friends.
dword errcode;
dword eip;
dword cs;
dword eflags;
}
Re:inline asm (DJGPP)
Posted: Tue Aug 03, 2004 8:03 am
by Eric
I think it works, but should it not be dword regs[7]? To me it seems like that cause I get "8" as the EIP, (which probably is the CS register)...
Re:inline asm (DJGPP)
Posted: Tue Aug 03, 2004 8:19 am
by Eric
No, it works, forgot about one register
But the values doesnt seems to be proper? I try to do 1/0, should at least one of the registers contain 1 and 0 then?
Re:inline asm (DJGPP)
Posted: Tue Aug 03, 2004 9:52 am
by Pype.Clicker
note that the 'error code' is not present for all exceptions. My technique is to push a fake code with exceptions that don't have one to keep consistency.
to check if it works or not, i suggest
Code: Select all
mov eax,0xcafebabe
mov ecx,0xdeadbeef
mov edx,0x1337da7a
mov ebx,0x1337c0de
mov esi,0x5555aaaa
mov edi,0xaaaa5555
int 3
for instance ...
Re:inline asm (DJGPP)
Posted: Tue Aug 03, 2004 2:01 pm
by Eric
Thank you. But there is a problem. I got the same handler for all exceptions (different handlers but the source is identical except for the C function I call), but some exceptions gets very weird. For instance, page fault looks good. But if I replace the "page fault trigger statement" with a divide by zero statement I get weird response. It sais that EIP = 8 and so on (which is impossible).
Re:inline asm (DJGPP)
Posted: Tue Aug 03, 2004 2:05 pm
by Eric
But if I change the struct to only have 7 elements instead of 8 in the regs-array, it works with divide by zero (and other exceptions get weird)
Re:inline asm (DJGPP)
Posted: Tue Aug 03, 2004 2:08 pm
by bkilgore
Eric wrote:
But if I change the struct to only have 7 elements instead of 8 in the regs-array, it works with divide by zero (and other exceptions get weird)
If you look at pype's message, you'll see that some exceptions put an error code on the stack, while some don't. You should have your stubs for each interrupt push a fake error code before calling the main interrupt handler for any interrupts that dont generate an error code so that you have a consistent stack...
Re:inline asm (DJGPP)
Posted: Tue Aug 03, 2004 2:20 pm
by Eric
thaenks!
Re:inline asm (DJGPP)
Posted: Tue Aug 03, 2004 2:28 pm
by Eric
But how should I push this because it?s not on top of the stack (the error code). Or I have to pop all registers and all that, push the errorcode, and then push the registers back
Re:inline asm (DJGPP)
Posted: Tue Aug 03, 2004 2:47 pm
by bkilgore
or better yet, push it before you push all the registers...
When an interrupt occurs the registers aren't on the stack, you have to push them all manually. Here's one example of how you might do it so that a fake error is pushed when it needs to be:
Code: Select all
isr8:
nop
nop
push byte 8
jmp all_ints???; double fault (error code)
isr9:
push byte 0
push byte 9
jmp all_ints???; coproc segment overrun (no error code)
isr0A:
nop
nop
push byte 0Ah
jmp all_ints???; bad TSS (error code)
all_ints:
push gs??????; push segment registers
push fs
push es
push ds
pushad??????; push 8 general-purpose registers
push esp???; push pointer to the registers
call c_interrupt_handler
add esp, 4?; drop pointer to the registers
popad??????; pop 8 general-purpose registers
pop ds??????; pop segment registers
pop es
pop fs
pop gs
add esp,8???; drop exception number and error code
iretd??????; return from interrupt
Re:inline asm (DJGPP)
Posted: Tue Aug 03, 2004 2:55 pm
by Eric
So when an exception occurs, the EIP and all that arent pushed?? But if they are not, then it should be impossible to get them?
Re:inline asm (DJGPP)
Posted: Tue Aug 03, 2004 3:28 pm
by Eric
It works great now, thanks..
a thing I came to think of. When an exception occurs in windows console, it says that the cs and ds and all those registers has a base of 029d0000. How come, isnt windows using paging and a flat memory modell?