Assembly Converting MOV / MOVZX and MOVSX to C code (no inline asm)

11,172

movsx is move with sign-extend. Those set bits are a copy of the sign bit from the original value, and would be clear if the original wasn't negative. It works just like your other conversions, except you need to use a signed type instead of an unsigned one.

regs.d.eax = *(signed char *)(regs.d.edi); // movsx eax, byte ptr ds:[edi]
Share:
11,172
SSpoke
Author by

SSpoke

Pro programmer from the russia How to be a programmer in steps? 1). Set a goal what you wish to program.. 2). Make your program just work. (don't worry think much how messy your coding is.) 3). Fix all bugs you can find and do tests on each part to make sure no more bugs exist. 4). Finally start from scratch and re-write your program in a clean matter, this will be fast don't worry because you already did this once ;). 4). And always ask StackOverflow for advise on parts you are unsure.

Updated on June 09, 2022

Comments

  • SSpoke
    SSpoke almost 2 years

    For the asm emulator i'm trying to write to convert ASM code to equivalent working code just working.. best code would be the one that can either be done in one line or two-three the most, don't care about speed.

    From my understanding. MOVZX would be the same as MOV.. if done in C++.

    MOV conversion.

    MOV ESI,DWORD PTR [ESP+8]
    

    would be like

    regs.d.esi = *(unsigned int *)(regs.d.esp+0x00000008);
    

    MOVZX conversion.

    MOVZX EAX,BYTE PTR DS:[EDI]
    

    would be like

    regs.d.eax = *(unsigned char *)(regs.d.edi);
    

    pretty much the same thing no change what so ever.

    Now MOVSX i'm having trouble converting to a simple C code.. seems to be the same as the two above.. except it attempts to append as much fully set bits in front of the value moved as possible.. like

    000000C7 becomes FFFFFFC7

  • SSpoke
    SSpoke over 12 years
    How about.. MOVSX EAX,AL is this correct? regs.d.eax = (signed char)(regs.h.al);
  • ughoavgfhw
    ughoavgfhw over 12 years
    @SSpoke You need to be careful about casting between different integer types, but I'm pretty sure casting between signed and unsigned types of the same size is safe. (You don't need to worry about the implicit cast to the type of regs.d.eax, since that is the actual movsx)
  • SSpoke
    SSpoke over 12 years
    al = unsigned char although. still not safe? it's already all applied.
  • ughoavgfhw
    ughoavgfhw over 12 years
    @SSpoke No, casting between types of the same size is safe (At least it worked right in my quick tests. Maybe someone can quote the standard?). You could have run into problems if al was some other size.
  • SSpoke
    SSpoke over 12 years
    thanks thats what I wanted to know it will never be another size. union _regs { struct { unsigned int eax, ebx, ecx, edx, esi, edi, ebp, esp; } d; struct { unsigned short ax, hax, bx, hbx, cx, hcx, dx, hdx, si, hsi, di, hdi, bp, hbp, sp, hsp; } x; struct { unsigned char al, ah, hax[2], bl, bh, hbx[2], cl, ch, hcx[2], dl, dh, hdx[2], rest[16]; } h; } regs;