I'm trying to assign a decimal value into a REAL8 local variable. However, the only quirky way I've found is to convert a decimal number to a IEEE 754 64 bit number.
For example, here's a float MASM 64-bit example that assigns a value of 1.5 to the local variable stop, then subtracts the global start time of 1.1, yielding the correct 0.4 result:
float.asm
option casemap:none
externdef printf : near
.data
szStop db "stop: %lf",0
ALIGN 8
start REAL8 1.1
.code
main proc
LOCAL stop:REAL8
; Convert decimal number to IEEE 754 64 bit number:
; https://www.ultimatesolver.com/en/ieee-754
;
; 1.5 -> 0011111111111000000000000000000000000000000000000000000000000000 -> 4609434218613702656
MOV RAX,4609434218613702656
MOV stop,RAX
FLD QWORD PTR stop
FSUB QWORD PTR start
FSTP QWORD PTR stop
PUSH RSP
PUSH QWORD PTR [RSP]
AND SPL,0F0h
MOV RDX,stop
LEA RCX,szStop
SUB RSP,32
CALL printf
LEA RSP,[RSP+40]
POP RSP
ret
main endp
end
Assembled using these batch commands:
float.bat
@echo on
if not defined DevEnvDir (
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat"
)
ml64.exe float.asm /link /subsystem:console /defaultlib:kernel32.lib /defaultlib:user32.lib /defaultlib:libcmt.lib
The output is correct:
Question
Is there a better way to handle decimal numbers in MASM?
Maybe other assemblers handle floats better?
I'm trying to assign a decimal value into a REAL8 local variable. However, the only quirky way I've found is to convert a decimal number to a IEEE 754 64 bit number.
MOV RAX,4609434218613702656 MOV stop,RAX FLD QWORD PTR stop
You have hardcoded the decimal number 1.5 in the mov rax
instruction. For this you had to convert the number yourself.
You can do easier and forget about conversion while using the REAL8
directive:
...
db 48h, 0B8h ; REX prefix, MOV RAX opcode
REAL8 1.5 ; 64-bit immediate
mov stop, rax ; Loading the local variable
fld QWORD PTR stop ; Loading st0
...
Alternatively, put the (hardcoded) number anywhere you like in your program and fld
it from there:
ALIGN 8
start REAL8 1.1
num REAL8 1.5
...
fld QWORD PTR num
...
or
...
fld QWORD PTR num
...
ret
ALIGN 8
num REAL8 1.5
main endp