Anyone know why this crashes when marked line is commented out?

_execstart:

mov ebp, esp ; save stack pointer

push eax ; save eax

push ebx ; save ebx

push esi ; save esi

mov esi, [_curinst] ; load instruction pointer into edi

mov [_errstate], dword INST_OK ; set errstate to OK


push dword _beginmessage ; put message onto the stack

call _printf ; print the message


_execloop:

lodsbzx ; move instruction into eax

shl eax, 2 ; multiply by four to get index within jumptable

mov ebx, [eax+jumptable] ; get address to jump to


jumpbase:

inst_nop: ; instruction: nop

jmp inst_end ; do nothing, jump to end


inst_nsi: ; unsupported instruction

mov [_errstate], dword INST_NOTSUPPORTED ; set error state

jmp inst_end ; jump to end


inst_end:

mov [_curinst], edi ; save current instruction

pop esi ; restore esi

pop ebx ; restore ebx

pop eax ; restore eax


push dword _endmessage ; put message onto the stack

call _printf ; print the message

mov esp, ebp ; restore stack pointer

; it will crash if the above line is commented out.

; i guess it is a stack misalignment, but i don't know why!?

ret




Anyone know what is causing it to crash? Calling _execstart from a C program.


Comments

  • That's my idea why this happens:

    If your routine is called the offset where the CPU shall return to after completing the subroutine is stored onto the stack (word SS:SP). Now you save SP in BP and change SP. Now SS:SP doesn't point to the word containing the return adress - but that's ok as long as you restore the old SP before returning.

    If you do not do so, the word pointed to by the "wrong" SP is used as return adress - and in most cases that's anything but the correct return adress, so the CPU returns to a random adress. In other words: a random code is executed and in most cases the computer crashes.

    So keep the line in! Why did you want to remove it at all?


    Greetings,


    blackbird


  • : _execstart:

    : mov ebp, esp ; save stack pointer

    : push eax ; save eax

    : push ebx ; save ebx

    : push esi ; save esi

    : mov esi, [_curinst] ; load instruction pointer into edi

    : mov [_errstate], dword INST_OK ; set errstate to OK


    : push dword _beginmessage ; put message onto the stack

    : call _printf ; print the message


    : _execloop:

    : lodsbzx ; move instruction into eax

    : shl eax, 2 ; multiply by four to get index within jumptable

    : mov ebx, [eax+jumptable] ; get address to jump to


    : jumpbase:

    : inst_nop: ; instruction: nop

    : jmp inst_end ; do nothing, jump to end


    : inst_nsi: ; unsupported instruction

    : mov [_errstate], dword INST_NOTSUPPORTED ; set error state

    : jmp inst_end ; jump to end


    : inst_end:

    : mov [_curinst], edi ; save current instruction

    : pop esi ; restore esi

    : pop ebx ; restore ebx

    : pop eax ; restore eax


    : push dword _endmessage ; put message onto the stack

    : call _printf ; print the message

    : mov esp, ebp ; restore stack pointer

    : ; it will crash if the above line is commented out.

    : ; i guess it is a stack misalignment, but i don't know why!?

    : ret


    :

    : Anyone know what is causing it to crash? Calling _execstart from a C program.


    I can take a guess, although I've never called a C function from an asm routine. However, when interfacing with C functions, the default calling convention is "cdecl", which means the calling function is responsible for removing parameters that were pushed onto the stack. If printf is using this method (I'm assuming it is), then you are responsible for popping _beginmessage and _endmessage off the stack when printf returns. printf() will not do it for you. (The compiler usually handles these things, but in asm its your job).


    Rock


  • I have them commented out now, but it still exhibits the same behavior. It crashes unless I explicit reset the stack pointer. It also crashes if I do not have the printf statement before I call the stub in C...


  • : I have them commented out now, but it still exhibits the same behavior. It crashes unless I explicit reset the stack pointer. It also crashes if I do not have the printf statement before I call the stub in C...


    How about this. I'm pretty sure you need to preserve ebp as well esp, because most likely the caller is using ebp as well. Try pushing ebp 1st thing in your routine, and pop it after you restore esp.


    Rock


  • I tried using popa and pusha, which copy all of the general registers, and it works just as it did with the "mov esp, ebp" at the end. I can't figure out why it crashes when I don't call printf before I called execstart:


    printf("Entering ASM..."); // will crash if line not present

    execstart();

    printf("back.");


    execstart is declared to be a pointer to a function of type void function(void), so it shouldn't need to push any return values.

    Any more ideas?





  • : I tried using popa and pusha, which copy all of the general registers, and it works just as it did with the "mov esp, ebp" at the end. I can't figure out why it crashes when I don't call printf before I called execstart:


    : printf("Entering ASM..."); // will crash if line not present

    : execstart();

    : printf("back.");


    : execstart is declared to be a pointer to a function of type void function(void), so it shouldn't need to push any return values.

    : Any more ideas?


    I'm all out. I'd say use pushad/popad for the 32 bit registers, but besides that I've got nothing. Just try commenting out almost everything and see what happens. Try:


    pushad

    mov ebp, esp


    mov esp, ebp

    popad

    ret


    At a minimum, this should definately work (unless I'm forgetting something). Then start adding lines back in until it fails.

    Have you tried stepping though this with a debugger. If its a protected mode program, the cpu should throw an exception when it crashes, which the debugger SHOULD catch and tell you what went wrong.


    Rock


Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories