Say I have the following code written in (AT&T) Assembly:
push qword 0
push qword 0
mov rax, 2 ;Tell rax we receive 2 floats
mov rdi, floatformat ;floatformat db "%lf %lf",0
mov rsi, rsp ;I am assuming my logic flaw is in these two lines
mov rdx, rsp
call scanf
pop rax ;Clean up the stack
pop rax
movsd xmm0, [rsi] ;This does not give the value I want
As stated in the comments above, I want xmm0
to hold the first float the user types in when call scanf
is performed, but only receive the second float. I am aware that this is most likely due to the mov rdx, rsp
operation, but if that is not performed, my program does not operate correctly to read in the user inputs.
How can I get the first float the user types in? I have tried researching scanf
calling conventions but have yet to find a clear answer.
%lf
is a double
, not a single precision float
. And no, the 2 args you're passing to scanf are double *
, not double
, so you should set AL=0
not 2
.
Anyway, your problem is that you passed the same pointer for both output operands. And that scanf
destroys its arg-passing registers, like the calling convention allows it to. (What registers are preserved through a linux x86-64 function call)
The C equivalent is like scanf("%lf %lf", &b, &b)
after reserving stack space for double a,b;
; assuming stack is 16-byte aligned to start with,
; e.g. if your function started with an odd number of pushes
sub rsp, 16
mov rsi, rsp ; pointer to low slot
lea rdx, [rsp+8] ; pointer to high slot
lea rdi, [rel format_string] ; use RIP-relative LEA for 64-bit static addresses
xor eax,eax ; 0 FP args in regs to a variadic function
call scanf ; scanf(fmt, &tmp0, &tmp1)
movaps xmm0, [rsp] ; load both doubles
add rsp, 16 ; now tmp0 and tmp1 are below RSP, in the red-zone
movsd xmm1, [rsp-8] ; or shuffle xmm0 to get tmp1 from the high half.
dummy push/pop is usually only worth it (instead of add rsp, imm8
) for one stack slot, and then mostly if you're going to call
right away instead of explicitly reference RSP. Doing that will insert a stack-sync uop.