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
。