CF、ZF、SF 和 OF 是 CC(条件代码)寄存器中的单数位。还有其他位在其他条件下设置。每当 CPU 执行某些指令(包括add
和sub
)时,它都会根据操作的结果设置这些位。指令cmp
和test
功能分别与sub
和and
指令相同,只是它们完全丢弃结果,唯一的输出是条件标志。
假设我们有以下 C 代码:
int a, b;
...
a -= b;
if(a < 0)
{
// stuff...
}
一个天真的编译器可能会这样编译它:
; Suppose a is in the eax register and b is in the edx register
sub %eax, %edx ; subtract b from a, store result in a
cmp $0, %eax ; compare a to 0
jl end_of_stuff ; if a < 0, goto end_of_stuff
; code for stuff goes here
end_of_stuff:
; code after if block goes here
然而,一个更聪明的编译器会意识到sub
指令已经设置了条件代码,所以它可以像这样编译它:
sub %eax, %edx
jl end_of_stuff ; if a < 0, goto end_of_stuff
; code for stuff goes here
end_of_stuff:
; code after if block goes here
请注意,jl
当且仅当 SF ≠ OF 时,指令(小于时跳转)才会跳转。也就是说,如果结果为负且未发生溢出,或者结果为正且确实发生了溢出,则跳转。这对于确保在差值溢出(例如与 比较)时获得正确结果是必要INT_MIN
的INT_MAX
。