I'm working on a MASM32 project that performs arithmetic operations. We have to use the coprocessor (8087 instruction set) to use the floating point unit. So, supose my floating point limit is 100.0
then every number must be less than the limit. I'm trying to sum two numbers and then compare the result but it doesn't work.
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
include c:\masm32\include\masm32rt.inc
.data
;Variables de comparación.
FP_max DD 100
;Variables volcadas de la tabla de símbolos.
_a DD 25
_b DD 80.0
.code
start:
fild _a
fild _b
fadd
fcom FP_max ;compare ST(0) with the value of the real8_var variable
fstsw ax ;copy the Status Word containing the result to AX
sahf ;transfer the condition codes to the CPU's flag register
ja overflow ;when all flags are 0
jmp end_program
overflow:
print "ERROR: overflow.", 13, 10, 0
jmp end_program
end_program:
invoke ExitProcess, 0
end start
My question is: what i'm doing wrong? How can it fix it? Thanks!
fild
is an integer->FP load. fld
is a float load. (Your assembler magically infers that you want a 32-bit load based by looking at the first directive after the label. The same instruction can load 64-bit integer or FP.)
dd
chooses integer or float encoding for the number based on whether there's a decimal point or not in the expression. (MASM probably has other ways to force FP interpretation, like REAL4. (Float data example using Masm)
You use fild _b
, but _b
holds a 32-bit binary floating point value. Treating that bit-pattern as a 32-bit integer is probably not what you meant to do.
Use _b DD 80
instead of _b DD 80.0
, or use fld _b
instead of fild _b
.
You have the reverse problem with FP_max DD 100
, because you load it from memory with fcom
. Make it REAL4
.
(Or use ficom
, but note that there's not ficomi
instruction to compare with an integer and set flags directly. There's fcomi
(which you should use) that compares floats, and there's ficom
which is like fild
+ fcomp
but without needing an extra FP register. Same idea as fiadd
).
You should probably be using faddp
and fcomip
to also pop the x87 stack, so you don't leave it unbalanced.
See some of the x87 links in the x87 tag wiki.