FromNandの日記

自分的備忘録

【EFLAGS】符号あり・なしにおける条件ジャンプについて【CF・OF・SF】

【CF・OF・SFについて】

CF → 符号なし計算で使用され、「足し算で繰り上がりした場合」「CMP A, B」において「A < B」である場合にセットされます

OF → 符号あり計算で使用され、「正 + 正 = 負」「負 + 負 = 正」「正 - 負 = 負」「負 - 正 = 正」というように、符号あり整数で表現できない数になった時にセットされます。

SF → 最上位ビット(MSB)がセットされます。

 

【どんな命令でEFLAGSはセットされるのか】

CMP命令やTEST命令などはもちろんですが、通常にADD、SUBといった命令でもセットされます。

MOV命令・JMP命令などではセットされません。

 

【符号なしジャンプ命令の場合】

JA (A > B) → CF == 0 && ZF == 0

JB (A < B) → CF == 1

JAE (A >= B) → CF == 0

JBE (A <= B) → CF == 1 || ZF == 1

 

【符号ありジャンプ命令の場合】

JG (A > B) → ZF == 0 && (SF == OF)

JL (A < B) → SF != OF

JGE (A >= B) → SF == OF

JLE (A <= B) → ZF == 1 || (SF != OF)

 

【符号ありの場合における補足】

符号ありの場合の「SF == OF」や「SF != OF」の部分が分かりにくいと思うので補足しておきます。

 

実は符号あり計算の途中式と結果のパターンは全部で8つあります。(ゼロになる場合は除いてありますが...)

正 - 正 → 正 (SF == 0 OF == 0)

正 - 正 → 負 (SF == 1 OF == 0)

正 - 負 → 正 (SF == 0 OF == 0)

正 - 負 → 負 (SF == 1 OF == 1) → 「正 - 負 → 負」は変なのでOF == 1

負 - 正 → 正 (SF == 0 OF == 1) → 「負 - 正 → 正」は変なのでOF == 1

負 - 正 → 負 (SF == 1 OF == 0)

負 - 負 → 正 (SF == 0 OF == 0)

負 - 負 → 負 (SF == 1 OF == 0)

この8つのパターンにおいて「左の値 - 右の値」の結果のフラグを見て「SF == OF」の場合は「左の値 >= 右の値」となっています。

逆に「SF != OF」の場合は「左の値 < 右の値」となっています。

x86ではこの特性を利用して(更にZFも参考にして)、条件ジャンプを実現しています。

 

【ジャンプ命令の別称】

ジャンプ命令には他にもたくさんの呼び方があります。

例えば、JA命令はJNBE命令と同値です。

 

【参考】

https://dixq.net/forum/viewtopic.php?f=3&t=20777