2016-12-26 77 views
1

由於我的主要操作系統是Linux,並在Visual Studio上有項目,我決定使用聯機編譯器來實現它。我發現許多人建議使用this。因此,這裏是我的代碼:大會:JA和JB工作不正確

#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不是把ares,否則res1。但似乎無論我在變量a它總是跳midi和結果總是res = whatever is in a。希望你能幫助。對不起,如果我的問題很愚蠢,我剛開始學習裝配。謝謝:)

P.S
同樣的事情會發生與JB卻截然相反。它總是打印res1 = whatever is in b

回答

5

this page

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

但是你JA midi正在測試CPU標誌。

它接着說:

FCOMI和FCOMIP工作就像FCOM和FCOMP, 的相應形式,但其結果直接寫入到CPU標誌寄存器,而 比FPU狀態字,所以他們可以立刻跟着 條件跳轉或有條件的移動指令。

+0

我得到一個錯誤說'source_file.cpp(13):錯誤C2414:非法數字operands' – Rasty

+0

的@Rasty似乎'FCOMI'不能把內存操作 - 它加載到寄存器中。但是,你有基本的原因,你的代碼不起作用。 –

+0

對不起,我沒有看到你的答案,當我貼我的:(我保持它,因爲我已經寫了它 –

4

這是一個常見的錯誤,FCOM不會設置標誌的標誌寄存器,它設置的條件碼標誌的FPU狀態字。
Intel manual 2

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

Condition codes set by FCOM

在那裏你可以看到C3需要的ZFCFC1的作用。使用FCOMI/FUCOMI(及其變體)相應地設置標誌。

執行的ST(0)和ST(i)和設置狀態標誌ZF,PF,和 CF在EFLAGS寄存器根據結果[寄存器的內容的一個無序的比較表是相同的如上所述,在C2PF]。

FCOMIFUCOMI之間的區別是,後者允許無序操作數,即qNaNs。


另外,您仍然可以使用FCOM但然後將條件碼標誌用:

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

英特爾設計fnstsw能與sahf兼容。
前者移動C3C2C1至位6,位2分別和第0位,的AH
後者設置的標誌爲RFLAGS(SF:ZF:0:AF:0:PF:1:CF) ← AH


您也可以testax直接fnstsw ax後的建議中第8.3.6.1 分支上的x87 FPU條件代碼的manual 1

Constants to test AX against after fnstsw for various conditions