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

2

7

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

Iou answered 14/10, 2011 at 1:28 Comment(0)
P
5

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]
Pogonia answered 14/10, 2011 at 1:32 Comment(5)
How about.. MOVSX EAX,AL is this correct? regs.d.eax = (signed char)(regs.h.al);Iou
@Iou 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)Pogonia
al = unsigned char although. still not safe? it's already all applied.Iou
@Iou 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.Pogonia
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; Iou
S
0

The fastest way to find very fast C equivalents of MOVSX and MOVXZ is just integer variable assignment from a type with lower bits to a type with higher bits. Both variables have to be typecasted either to signed type (for MOVSX) or unsigned type (MOVZX).

For example, C equivalent of "movzx ebx, al" would be:

(unsigned int) ebx = (unsigned char) al;

C equivalent of "movsx ebx, al" would be:

(signed int) ebx = (signed char) al;

Just make sure your char type is 8 bit and your int type is 32 bit, and so on.

Sigmatism answered 11/5, 2017 at 9:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.