Assembly Language for Beginners

(nextflipdebug2) #1

1.19. FLOATING-POINT UNIT


lwc1 $f15, $LC1
; call pow():
jalr $t9
or $at, $zero ; branch delay slot, NOP
lw $gp, 0x20+var_10($sp)
; copy result from $f0 and $f1 to $a3 and $a2:
mfc1 $a3, $f0
lw $t9, (printf & 0xFFFF)($gp)
mfc1 $a2, $f1
; call printf():
lui $a0, ($LC2 >> 16) # "32.01 ^ 1.54 = %lf\n"
jalr $t9
la $a0, ($LC2 & 0xFFFF) # "32.01 ^ 1.54 = %lf\n"
; function epilogue:
lw $ra, 0x20+var_4($sp)
; return 0:
move $v0, $zero
jr $ra
addiu $sp, 0x20


.rodata.str1.4:00000084 $LC2: .ascii "32.01 ^ 1.54 = %lf\n"<0>


; 32.01:
.rodata.cst8:00000098 $LC0: .word 0x40400147 # DATA XREF: main+20
.rodata.cst8:0000009C dword_9C: .word 0xAE147AE1 # DATA XREF: main
.rodata.cst8:0000009C # main+18
; 1.54:
.rodata.cst8:000000A0 $LC1: .word 0x3FF8A3D7 # DATA XREF: main+24
.rodata.cst8:000000A0 # main+30
.rodata.cst8:000000A4 dword_A4: .word 0xA3D70A4 # DATA XREF: main+14


And again, we see hereLUIloading a 32-bit part of adoublenumber into $V0. And again, it’s hard to
comprehend why.


The new instruction for us here isMFC1(“Move From Coprocessor 1”). The FPU is coprocessor number 1,
hence “1” in the instruction name. This instruction transfers values from the coprocessor’s registers to
the registers of the CPU (GPR). So at the end the result ofpow()is moved to registers $A3 and $A2, and
printf()takes a 64-bit double value from this register pair.


1.19.7 Comparison example.


Let’s try this:


#include <stdio.h>


double d_max (double a, double b)
{
if (a>b)
return a;


return b;
};


int main()
{
printf ("%f\n", d_max (1.2, 3.4));
printf ("%f\n", d_max (5.6, -4));
};


Despite the simplicity of the function, it will be harder to understand how it works.


x86


Non-optimizing MSVC


MSVC 2010 generates the following:

Free download pdf