例如,对于以下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
当基于〜(SF ^ OF)&amp; ~ZF的评估执行cmovg时,当CPU执行指令cmp%eax%edx时,CF也会被设置吗?注意,二进制形式负数-1与2 <&lt; 32-1。
相同答案 0 :(得分:0)
它从变量的类型中提取此类信息。编译器在语义分析阶段执行此操作,它将语义信息添加到解析树并构建符号表。还有一些information。理解编译器的好书是this一个
答案 1 :(得分:0)
你的意思是问“ cpu 如何判断操作数是否已签名”?因为这就是你的问题。答案是:它没有。值既没有签名也没有真正的无符号,它们只是“一堆”。指令可以有有符号或无符号的变体,例如分支(但不是比较),除法,右移和长乘法。加法,减法(和比较,它只是影响标志的减法)和短乘法(你没有得到额外的上半部分)没有签名和无符号版本,但是一个版本对两者都是正确的。结果不受签名的影响。
对于那些结果不受签名影响的指令,标志有时是。无论哪种方式,ZF和SF显然是相同的,但是当溢出时,签名显然很重要。但由于OF和CF是单独的标志,因此可以设置不同的值。
例如,mov eax, -2 \ add eax, eax
设置CF因为有无符号溢出,但它没有设置OF,因为没有签名溢出。你可以把它解释为没有溢出的带符号的加法,或者作为无符号的加法溢出(或者甚至两者都有,但这几乎从来没用过),但唯一的区别在于你关心的标志
编译器显然知道应该签名什么以及应该是无符号的,因此可以在sar
和shr
(右移)和idiv
和{之间进行选择。 {1}}(对于除法),它为div
和cmovcc
选择了CC。