1.19. FLOATING-POINT UNIT
FLDandFSTPmove variables between the data segment and the FPU stack.pow()^120 takes both values
from the stack and returns its result in theST(0)register. printf()takes 8 bytes from the local stack
and interprets them asdoubletype variable.
By the way, a pair ofMOVinstructions could be used here for moving values from the memory into the
stack, because the values in memory are stored in IEEE 754 format, and pow() also takes them in this
format, so no conversion is necessary. That’s how it’s done in the next example, for ARM:1.19.6.
ARM + Non-optimizing Xcode 4.6.3 (LLVM) (Thumb-2 mode)
_main
var_C = -0xC
PUSH {R7,LR}
MOV R7, SP
SUB SP, SP, #4
VLDR D16, =32.01
VMOV R0, R1, D16
VLDR D16, =1.54
VMOV R2, R3, D16
BLX _pow
VMOV D16, R0, R1
MOV R0, 0xFC1 ; "32.01 ^ 1.54 = %lf\n"
ADD R0, PC
VMOV R1, R2, D16
BLX _printf
MOVS R1, 0
STR R0, [SP,#0xC+var_C]
MOV R0, R1
ADD SP, SP, #4
POP {R7,PC}
dbl_2F90 DCFD 32.01 ; DATA XREF: _main+6
dbl_2F98 DCFD 1.54 ; DATA XREF: _main+E
As it was mentioned before, 64-bit floating pointer numbers are passed in R-registers pairs.
Thiscodeisabitredundant(certainlybecauseoptimizationisturnedoff), sinceitispossibletoloadvalues
into the R-registers directly without touching the D-registers.
So, as we see, the_powfunction receives its first argument inR0andR1, and its second one inR2andR3.
The function leaves its result inR0andR1. The result of_powis moved intoD16, then in theR1andR2
pair, from whereprintf()takes the resulting number.
ARM + Non-optimizing Keil 6/2013 (ARM mode)
_main
STMFD SP!, {R4-R6,LR}
LDR R2, =0xA3D70A4 ; y
LDR R3, =0x3FF8A3D7
LDR R0, =0xAE147AE1 ; x
LDR R1, =0x40400147
BL pow
MOV R4, R0
MOV R2, R4
MOV R3, R1
ADR R0, a32_011_54Lf ; "32.01 ^ 1.54 = %lf\n"
BL __2printf
MOV R0, #0
LDMFD SP!, {R4-R6,PC}
y DCD 0xA3D70A4 ; DATA XREF: _main+4
dword_520 DCD 0x3FF8A3D7 ; DATA XREF: _main+8
x DCD 0xAE147AE1 ; DATA XREF: _main+C
(^120) a standard C function, raises a number to the given power (exponentiation)