inline asm (DJGPP)

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
Eric

inline asm (DJGPP)

Post 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.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:inline asm (DJGPP)

Post 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;
}
Eric

Re:inline asm (DJGPP)

Post 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)...
Eric

Re:inline asm (DJGPP)

Post 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?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:inline asm (DJGPP)

Post 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 ...
Eric

Re:inline asm (DJGPP)

Post 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).
Eric

Re:inline asm (DJGPP)

Post 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)
bkilgore

Re:inline asm (DJGPP)

Post 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...
Eric

Re:inline asm (DJGPP)

Post by Eric »

thaenks!
Eric

Re:inline asm (DJGPP)

Post 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
bkilgore

Re:inline asm (DJGPP)

Post 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
Eric

Re:inline asm (DJGPP)

Post 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?
Eric

Re:inline asm (DJGPP)

Post 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?
Post Reply