问题
Since my main OS is linux and have project on visual studio, I decided to use online compilers to achieve it. I found this which was suggested by many. So here is my code:
#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;
}
My goal is simple, if a
is greater that b
than put a
in res
, otherwise in res1
. But it seems like whatever I have in variable a
it always jumps on midi
and result is always res = whatever is in a
. Hope you can help. Sorry if my questions is silly, I've just started to learn assembly. thanks :)
P.S
same thing goes with JB
but the opposite. It always prints res1 = whatever is in b
.
回答1:
From this page:
FCOM compares ST0 with the given operand, and sets the FPU flags accordingly.
But your JA midi
is testing the CPU flags.
It goes on:
FCOMI and FCOMIP work like the corresponding forms of FCOM and FCOMP, but write their results directly to the CPU flags register rather than the FPU status word, so they can be immediately followed by conditional jump or conditional move instructions.
回答2:
This is a common pitfall, FCOM doesn't set the flags in the flags register, it sets the condition code flags in the FPU status word.
From Intel manual 2:
Compares the contents of register
ST(0)
and source value and sets condition code flags C0, C2, and C3 in the FPU status word according to the results (see the table below)
Where you can see that C3 takes the role of ZF and C1 of CF.
Use FCOMI/FUCOMI (and variants) to set the flags accordingly.
Performs an unordered comparison of the contents of registers ST(0) and ST(i) and sets the status flags ZF, PF, and CF in the EFLAGS register according to the results [Table is identical to the above, where C2 is PF].
The difference between FCOMI
and FUCOMI
is that the latter allow for unordered operands, i.e. qNaNs.
Alternatively you can still use FCOM
but then move the condition codes to the flags with:
fnstsw ax ;FP Not-checked STore Status Word in AX
sahf ;Store AH into flags
Intel designed fnstsw to be compatible with sahf.
The former moves C3, C2 and C1 to bit6, bit2 and bit0, respectively, of AH
.
The latter set the flags as RFLAGS(SF:ZF:0:AF:0:PF:1:CF) ← AH
.
You can also test ax
directly after the fnstsw ax
as suggested in Section 8.3.6.1 Branching on the x87 FPU Condition Codes of manual 1.
来源:https://stackoverflow.com/questions/41334026/assembly-ja-and-jb-work-incorrectly