1.19. FLOATING-POINT UNIT
.rodata.cst8:000000B8 $LC0: .word 0x40091EB8 # DATA XREF: f+C
.rodata.cst8:000000BC dword_BC: .word 0x51EB851F # DATA XREF: f+4
.rodata.cst8:000000C0 $LC1: .word 0x40106666 # DATA XREF: f+10
.rodata.cst8:000000C4 dword_C4: .word 0x66666666 # DATA XREF: f
The new instructions here are:
- LWC1loads a 32-bit word into a register of the first coprocessor (hence “1” in instruction name).
A pair ofLWC1instructions may be combined into aL.Dpseudo instruction.
- DIV.D,MUL.D,ADD.Ddo division, multiplication, and addition respectively (“.D” in the suffix stands
for double precision, “.S” stands for single precision)
There is also a weird compiler anomaly: theLUIinstructions that we’ve marked with a question mark. It’s
hard for me to understand why load a part of a 64-bit constant ofdoubletype into the $V0 register. These
instructions has no effect. If someone knows more about it, please drop an email to author^119.
1.19.6 Passing floating point numbers via arguments.
#include <math.h>
#include <stdio.h>
int main ()
{
printf ("32.01 ^ 1.54 = %lf\n", pow (32.01,1.54));
return 0;
}
x86
Let’s see what we get in (MSVC 2010):
Listing 1.207: MSVC 2010
CONST SEGMENT
real@40400147ae147ae1 DQ 040400147ae147ae1r ; 32.01
real@3ff8a3d70a3d70a4 DQ 03ff8a3d70a3d70a4r ; 1.54
CONST ENDS
_main PROC
push ebp
mov ebp, esp
sub esp, 8 ; allocate space for the first variable
fld QWORD PTR real@3ff8a3d70a3d70a4
fstp QWORD PTR [esp]
sub esp, 8 ; allocate space for the second variable
fld QWORD PTR real@40400147ae147ae1
fstp QWORD PTR [esp]
call _pow
add esp, 8 ;return back place of one variable.
; in local stack here 8 bytes still reserved for us.
; result now in ST(0)
fstp QWORD PTR [esp] ; move result from ST(0) to local stack for printf()
push OFFSET $SG2651
call _printf
add esp, 12
xor eax, eax
pop ebp
ret 0
_main ENDP
(^119) [email protected]