2010-04-13 41 views
7

我是第一次尝试组装的新手程序员。对不起,如果这是一个令人难以置信的跛脚问题。x86汇编中的操作数大小冲突?

我有一个字符存储在EAX寄存器中,但我需要将它移动到我的DL寄存器。当我尝试:mov dl,eax我得到一个错误C2443:操作数大小冲突。我知道eax寄存器是32位的,而dl是8位的...我是在做什么?我该如何解决这个问题。

回答

6

尝试

xor edx,edx 
mov dl, al 

吧?第一条指令将edx的“不必要的”高位清零(可选),然后将低8从eax移到edx。

正如其他人所指出的,movzx一步到位。值得一提的是,根据相同的观点,如果你在al中有的值,你可以使用“movsx edx,al”来填充edx的高位,并使用al的msb的一个副本,从而将签名al到edx的32位表示。

+0

没错。 EAX寄存器是32位宽,而DL只有8位。 您需要将AL移到DL,AL是EAX的子集。 – MPelletier 2010-04-13 00:57:15

+0

xoring edx只是一个不错的主意:)漂亮而干净。 – MPelletier 2010-04-13 00:58:39

+0

我不明白第一条指令。是不是'xor edx,edx'将%edx中的所有位清零? – 2010-04-13 01:11:45

3

如果你只是想访问EAX的低8位,然后使用人:

mov dl, al 

您可以通过更改访问的低8位,16位,或每个通用寄存器的32位字母在开始或结束。对于寄存器eax,使用eax意味着使用全部32位,ax是低16位,而al是低8位。 ebx的等价物分别是ebx,bx和bl,依此类推。

请注意,如果修改寄存器的低16位或8位,则高位不变。例如,如果你在eax中加载所有的1,然后将零加载到al中,那么eax的低8位将是零,而高24位将是1。

mov eax, -1 ; eax is all ones 
mov al, 0 ; higher 24 bits are ones, lower 8 bits are zeros 
+0

将al移入dl是基本情况。零填充或签名扩展可能是必要的,也可能不是必须的,因为在选择手工编码的装配时,您是 - 或者应该 - 在最低限度的,纯粹的解决方案之后:“很高兴拥有”是一种昂贵的奢侈品,并且自然被排除在外。 – 2013-09-02 08:48:47

11

你想要的可能是:

movzx edx, al 

这将复制到人d1和EDX的补零休息。这条单指令相当于这两条指令:

xor edx, edx 
mov dl, al 
+3

我更喜欢这个。 movzx负责所有的尾随位。耶为一些抽象! (我的热情应该背叛我缺乏组装经验)。 – MPelletier 2010-04-13 17:25:51