簡體   English   中英

匯編:JA和JB工作不正確

[英]Assembly: JA and JB work incorrectly

由於我的主要操作系統是linux,並且在Visual Studio上具有項目,因此我決定使用在線編譯器來實現它。 我發現是很多人建議的。 所以這是我的代碼:

#include <iostream>

using namespace std;
int main(void) {
float a = 1;
float b = 20.2;
float res = 0;
float res1 = 0;

_asm { 

    FLD a
    FCOM b
    JA midi
    JMP modi           

    midi:
    FST res
    JMP OUT

    modi:
    FST res1
    JMP OUT


}
    OUT:
cout << "res = " << res << endl;
cout << "res1 = " << res1 << endl;
return 0;
}

我的目標很簡單,如果a大於b不是a放入res ,否則放入res1 但是,無論我在變量a擁有什么,它總是跳到midi ,結果總是res = whatever is in a 希望能對您有所幫助。 抱歉,如果我的問題很愚蠢,我才剛剛開始學習匯編。 謝謝 :)

聚苯乙烯
JB也是如此,但相反。 它總是打印res1 = whatever is in b

從此頁面

FCOM將ST0與給定的操作數進行比較,並相應地設置FPU標志。

但是您的JA midi正在測試CPU標志。

它繼續:

FCOMI和FCOMIP的工作方式類似於FCOM和FCOMP的相應形式,但是將其結果直接寫入CPU標志寄存器而不是FPU狀態字,因此可以緊隨其后的是條件跳轉或條件移動指令。

這是一個常見的陷阱, FCOM不會在標志寄存器中設置標志,而是在FPU狀態字中設置條件代碼標志。
英特爾手冊2

比較寄存器ST(0)的內容和源值,並根據結果在FPU狀態字中設置條件代碼標志C0C2C3 (請參見下表)

FCOM設置的條件代碼

在這里您可以看到C3扮演ZF角色,而CF扮演C1角色。

使用FCOMI / FUCOMI (和變體)相應地設置標志。

對寄存器ST(0)和ST(i)的內容進行無序比較,並根據結果設置EFLAGS寄存器中的狀態標志ZF,PF和CF [表與上述相同,其中C2PF ] 。

FCOMIFUCOMI之間的區別在於,后者允許無序操作數,即qNaNs。


或者,您仍然可以使用FCOM但是可以使用以下命令將條件代碼移動到標志:

fnstsw ax        ;FP Not-checked STore Status Word in AX
sahf             ;Store AH into flags

英特爾將fnstsw設計為與sahf兼容。
前者將C3C2C1分別移動到AH bit6,bit2和bit0。
后者將標志設置為RFLAGS(SF:ZF:0:AF:0:PF:1:CF) ← AH


您還可以按照手冊1 的x87 FPU條件代碼的第8.3.6.1節“ 分支”中的建議,在fnstsw ax之后直接test ax

fnstsw之后針對各種條件測試AX的常量

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM