Print a Floating Point Value in ARM64 assembly
==============================================
I've found that calling the function "printf" to print a
floating point value from an Assembly program is not trivial.
First, to use the specifier "%f", you need to have a double-precision
value in the corresponding operand (a register).
The second thing, I've found is that an immediate value passed to
a register is of length 16 bits.
So, if you try a 32-bit or more numbers using the 'mov' or 'fmov'
commabd you will get:
* For an integer:
immediate value cannot be moved by a single instruction
* For a floating-point number:
invalid floating point constant at operand 2
An immediate floating number should be what the IEEE 754 standard defines
as half-precision value.
So, you'll need to load the value from an address instead using 'ldr'.
Searching the web, I've found in a Reddit discussion that the site
https://godbolt.org can help you generate Assembly code from C.
A useful command I found if you want to load a page and your CPU Support it
is "adrp"[1].
Yes, you can find amazing things on ".org" sites!
You can learn even more about the architecture from the architecture guide [2]
In my program [3], I use "ldr" to simply get the number from an address.
Nom let us talk a little bit about the IEEE 754 standard for double precision:
Double-precision numbers are represented by 64-bit fields:
* The highest bit is the sign (0 for positive, 1 for negative), where is zero?
well, according to IEEE 745, there are +0 and -0.
* Bits 52 thru 62 - the exponent. Holds a value between 0 and 7ffh.
* Bits 0 thru 51 - are the mantissa.
The rules:
1. When both the mantissa and the exponent are zeros, the real value
is +0 or -0 depending on the sign.
2. When the exponent is zero, the real value is mantisa / 2^52.
3. When the exponent is 7ffh and the mantissa is zero, the value is
+infinity or -infinity depending on the sign.
4. When the exponent is 7ffh and the mantissa is non-zero, the value
is NaN - not a number, but a computation error.
5. Otherwise, the real value is (1 + mantissa/2^52)*2^(exponent-3ff)
For example, when the requested number is 41.3:
1. 41.3 is a positive number, thus the sign digit is 0
2. 41.3 is greater than or equal to 32, and smaller than 64, thus
the exponent is 5+3ffh=404h
3. 41.3 / 32 = 1.290625
4. Let us subtract 1, the result is 0.290625
5. Multiply by 2^52 and convert to hexadecimal:
the mantissa is 4a66666666666h.
6. From steps 1,2 and 5, we get the result:
4044a66666666666
[1]
https://developer.arm.com/documentation/ddi0602/2022-09/Base-Instructions?lang=en
[2]
https://developer.arm.com/documentation/102374/latest/
[3]
gopher://zaibatsu.circumlunar.space/1/~zaphodb/phlog/callprintf.s