TL:DR:上記/以下の条件(符号なし整数など)を使用して、比較の結果をテストします。
さまざまな歴史的理由( FPステータスワードから//を介したFLAGSへのfcom
マッピングfstsw
sahf
(PProfcomi
の新機能)が一致)により、FPはOF/SFではなくセットCFを比較します。http://www.ray.masmcode.com/tutorial/fpuchap7.htmも参照してください。
これはすべて、 Intel64およびIA-32アーキテクチャソフトウェア開発者マニュアルの第2巻からのものです。
FCOMI
するフラグの一部のみを設定CMP
します。あなたのコードにはとが%st(0) == 9
あり%st(1) == 10
ます。(ロードされるスタックであるため)ボリューム2Aの3-348ページの表を参照すると、これが「ST0 <ST(i)」の場合であることがわかり、ZFとPFをクリアして設定します。 CF。一方、ページで。3-544巻 JG
2Aは、 「大きい場合は短くジャンプする(ZF=0およびSF=OF)」という意味を読み取ることができます。つまり、符号、オーバーフロー、ゼロフラグをテストしていますが、FCOMI
符号やオーバーフローは設定していません。
ジャンプしたい条件に応じて、可能な比較結果を見て、いつジャンプしたいかを決定する必要があります。
+ -------------------- + --- + --- + --- +
| 比較結果| Z | P | C |
+ -------------------- + --- + --- + --- +
| ST0> ST(i)| 0 | 0 | 0 |
| ST0 <ST(i)| 0 | 0 | 1 |
| ST0 = ST(i)| 1 | 0 | 0 |
| 順不同| 1 | 1 | 1 | 一方または両方のオペランドはNaNでした。
+ -------------------- + --- + --- + --- +
わかりやすくするために、この小さなテーブルを作成しました。
+ -------------- + --- + --- + ----- + -------------------- ---------------- +
| テスト| Z | C | Jcc | ノート|
+ -------------- + --- + --- + ----- + -------------------- ---------------- +
| ST0 <ST(i)| X | 1 | JB | CF = 1 |の場合、ZFは設定されません。
| ST0 <= ST(i)| 1 | 1 | JBE | ZFまたはCFのどちらでも問題ありません|
| ST0 == ST(i)| 1 | X | JE | この場合、CFは設定されません|
| ST0!= ST(i)| 0 | X | JNE | |
| ST0> = ST(i)| X | 0 | JAE | CFが明確である限り、私たちは良いです|
| ST0> ST(i)| 0 | 0 | JA | CFとZFの両方が明確でなければなりません|
+ -------------- + --- + --- + ----- + -------------------- ---------------- +
凡例:X:気にしない、0:クリア、1:セット
つまり、条件コードは、符号なし比較を使用する場合の条件コードと一致します。を使用している場合も同様ですFMOVcc
。
のいずれか(または両方)のオペランドfcomi
がNaNの場合、。を設定しますZF=1 PF=1 CF=1
。(FP比較では、、、、、または順序付けされていない4つの結果が考えられます)>
。コードがNaNで何をするかを気にする場合は、追加のまたはが必要になることがあります。ただし、常にではありません。たとえば、CF=0およびZF=0の場合にのみ真であるため、順序付けされていない場合は適用されません。順序付けされていないケースで以下と同じまたは等しい実行パスを使用する場合は、必要なのはそれだけです。<
==
jp
jnp
ja
ja
ここでは、印刷するJA
場合(つまりif (!(f2 > f1)) { puts("hello"); }
、)と印刷JBE
しない場合(に対応)を使用する必要がありますif (!(f2 <= f1)) { puts("hello"); }
。(ジャンプしない場合にのみ印刷するため、これは少し混乱する可能性があることに注意してください)。
2番目の質問について:デフォルトでfcomi
は何もポップしません。あなたはfcomip
ポップするその親しいいとこが欲しいです%st0
。使用後は常にfpuレジスタスタックをクリアする必要があるため、メッセージを出力したい場合は、プログラム全体で次のようになります。
.section .rodata
msg: .ascii "Hallo\n\0"
f1: .float 10.0
f2: .float 9.0
.globl main
.type main, @function
main:
flds f1
flds f2
fcomip
fstp %st(0) # to clear stack
ja leb # won't jump, jbe will
pushl $msg
call printf
addl $4, %esp
leb:
pushl $0
call exit