将汇编中的MOV/MOVZX和MOVSX转换为C代码(无内联汇编)

7

对于我正在尝试编写的汇编模拟器,我需要将汇编代码转换为等效的工作代码。最好的代码只需要一两行即可完成,速度不是很重要。

据我理解,如果在C++中完成,MOVZXMOV相同。

MOV 转换。

MOV ESI,DWORD PTR [ESP+8]

would be like

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

MOVZX 转换。
MOVZX EAX,BYTE PTR DS:[EDI]

会像是什么呢?
regs.d.eax = *(unsigned char *)(regs.d.edi);

基本上是相同的事情,没有任何改变。

现在我遇到了将 MOVSX 转换为简单的C代码的问题...似乎与上面两个相同...除了它试图在移动的值前面附加尽可能多的完全设置位..像

000000C7变成了FFFFFFC7

2个回答

5

movsx是带符号扩展移动指令。它会将原始值的符号位复制到设置的位上,如果原始值不是负数,则这些位会清零。它与其他转换指令类似,只不过需要使用有符号类型而不是无符号类型。

regs.d.eax = *(signed char *)(regs.d.edi); // movsx eax, byte ptr ds:[edi]

这个怎么样?MOVSX EAX,AL 这个正确吗?regs.d.eax = (signed char)(regs.h.al); - SSpoke
1
@SSpoke 你需要小心地在不同整数类型之间进行强制类型转换,但我非常确定在相同大小的有符号和无符号类型之间进行强制类型转换是安全的。(你不必担心对 regs.d.eax 类型的隐式转换,因为那是实际的 movsx) - ughoavgfhw
al = unsigned char 尽管如此。已经全部应用,仍然不安全吗? - SSpoke
1
@SSpoke 不,类型之间的转换是安全的(至少在我的快速测试中是这样的。也许有人可以引用标准?)。如果 al 是其他大小,你可能会遇到问题。 - ughoavgfhw
谢谢,这就是我想知道的,它永远不会是另一个大小。 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; - SSpoke

0

找到非常快速的MOVSX和MOVZX的C等效方法最快的方法就是将整数变量从低位类型分配给高位类型。这两个变量都必须强制转换为有符号类型(对于MOVSX)或无符号类型(MOVZX)。

例如,“movzx ebx,al”的C等效语句如下:

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

"movsx ebx, al" 的 C 语言等效语句为:

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

请确保您的char类型为8位,int类型为32位等等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接