# What is the use of moving a variable 3 times only to pass it back to the original register, with no calculations in between?

I'm reverse engineering a C++ binary using IDA, and there's one function that I don't quite understand.

``````x = dword ptr -8
var_4 = dword ptr -4

push    rbp
movss   rbp, rsp
sub     rsp, 10h
movss   [rbp+var_4], xmm0
mov     eax, [rbp+var_4]
mov     [rbp+x], eax
movss   xmm0, [rbp+x]
call    _sinf
leave
retn
``````

The eax register is overwritten right away, and I can't imagine that eax was loaded to pass as an argument to "sinf". What's the use of this? Or is it just a weird compiler optimization?

It looks like that the binary has been compiled without optimization. With optimization enabled the redundant instructions would have been removed. A similar example is shown below.

### Original code

``````#include <math.h>

float calculate(float v)
{
return sinf(v);
}
``````

### No optimization (-O0)

``````calculate(float):
push    rbp
mov     rbp, rsp
sub     rsp, 16
movss   DWORD PTR [rbp-4], xmm0
mov     eax, DWORD PTR [rbp-4]
mov     DWORD PTR [rbp-8], eax
movss   xmm0, DWORD PTR [rbp-8]
call    sinf
leave
ret
``````

### -O1

``````calculate(float):
sub     rsp, 8
call    sinf
ret
``````

### -O2/-O3

``````calculate(float):
jmp     sinf
``````

As you can see above, the redundant moves are generated only when optimizations aren't enabled. With higher levels, it progressively leads to smaller code.

• Thanks! One more quick question, I noticed that the xmm0 register is used to pass the floating point variable to sinf, and that the return value is stored in xmm0. Usually, on 64 bit, the first parameter to a function is passed through rdi, and the return value is stored in rax. Is it just different for floating point functions? I can't find a whole lot of documentation on the matter. Aug 26 '20 at 10:19
• @Magusviper Floating point values are passed/returned in `XMM` registers. Check the `X86_calling_conventions` article on Wikipedia.
– 0xec
Aug 26 '20 at 10:23