我知道这是一个非常简单的问题,但我找不到答案。
x86汇编中的寄存器(eax、ebx、edx等)是有符号还是无符号的?如果它们默认为有符号,那么如果我们将变量声明为unsigned int,计算机如何知道如何将寄存器视为无符号的呢?谢谢!
CPU并不知道,也不在意。相反,在特定操作中设置了Flags寄存器中的位,程序如何处理这些标志取决于源代码所告诉它的内容。
例如,
mov eax, 0FFFFFFFFh
test eax, eax
js isNegative
对比。
mov eax, 0FFFFFFFFh
test eax, eax
jb isNegative
第一个跳到'IsNegative',因为test
在这里设置了符号标志。第二个没有,因为test
将进位标志复位为0
,而jb
仅在它为1
时跳转。
x < 0
始终为false,因此在实际编程中,您实际上不会编写test same,same
/ jb
。该条件已知对于每个可能的EAX值(包括零)都是false(不采取)。也许更好的例子是cmp eax,10
用于有符号与无符号eax <10
。(然后,您需要使用jl
而不是js
来进行有符号条件。) - Peter Cordesx86中的32位寄存器默认为无符号。例如,从32位操作数移动到64位寄存器时,在长模式下始终进行零扩展。但每个指令根据其目的对寄存器都有自己的解释,例如“add”指令可以使用带符号或无符号的寄存器。有关详细信息,请参阅英特尔文档。
mov eax, ecx
中,两个操作数都是32位的。写入32位寄存器总是会隐式地将其零扩展到完整的64位寄存器,但是唯一显式执行32位到64位移动的方法是使用 movsxd rax, ecx
(进行符号扩展)。mov rax, ecx
无法汇编(操作数大小不匹配)。没有带有32位源的 movzx
形式,因为你不需要它(只需使用 mov
)。因此,实际上不可能* 明确地 * 零扩展64位。 - Peter Cordes