0

例如,对于下面的 C 表达式,

int x =-1; 
unsigned y = 1; 
if(x>y) 
x+=y;

在编译时,程序集版本可以如下所示,

(假设 x 在 %eax 中,y 在 %edx 中)

mov $-1 %eax
mov $1 %edx
mov %eax %edp
add %edx %edp
cmp %eax %edx
cmovg %edp %eax 

由于 cmovg 是基于 ~(SF^OF)&~ZF 的评估执行的,所以当 CPU 执行指令 cmp %eax %edx 时,CF 是否也会被设置?请注意,二进制形式的负数 -1 与 2<<32-1 相同。

4

2 回答 2

0

它从变量的类型中提取此类信息。编译器在语义分析阶段执行此操作,将语义信息添加到解析树并构建符号表。更多信息。一本理解编译器的好书就是

于 2013-07-02T09:57:26.310 回答
0

你的意思是问“ cpu如何决定一个操作数是否被签名”?因为这就是你的问题的样子。答案是:不会。值既不是有符号也不是真正无符号,它们只是“一堆位”。指令可以有有符号或无符号变体,例如分支(但不是比较)、除法、右移和长乘法。加法、减法(和比较,这是只影响标志的减法)和短乘法(你没有得到额外的上半部分)没有有符号和无符号版本,但一个版本对两者都正确。结果不受签名的影响。

对于那些结果不受符号影响的指令,标志有时会受到影响。ZF 和 SF 显然是相同的,但符号显然对于溢出时很重要。但由于 OF 和 CF 是独立的标志,它们可以设置不同的值。

例如,mov eax, -2 \ add eax, eax设置 CF 因为有无符号溢出,但它不设置 OF 因为没有有符号溢出。您可以将其解释为没有溢出的有符号加法或没有溢出的无符号加法(或者甚至两者都有,但这几乎没有用处),但唯一的区别在于您关心的标志

编译器显然知道什么应该是有符号的,什么应该是无符号的,因此可以在sarand shr(用于右移)和 between idiv(用于除法)之间进行选择,并且它为anddiv选择 CC 。cmovccjcc

于 2013-07-02T10:51:00.247 回答