如何在汇编中访问scanf调用的第一个参数



假设我在(AT&T(程序集中编写了以下代码:

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

如上所述,我希望xmm0在执行call scanf时保持用户键入的第一个浮点值,但只接收第二个浮点值。我知道这很可能是由于mov rdx, rsp操作造成的,但如果不执行,我的程序将无法正确读取用户输入。

如何获取用户键入的第一个浮点值?我尝试过研究scanf调用约定,但还没有找到明确的答案。

%lfdouble,而不是单精度float。不,传递给scanf的2个参数是double *而不是double,所以应该设置AL=0而不是2

无论如何,您的问题是为两个输出操作数传递了相同的指针并且scanf破坏其arg传递寄存器,就像调用约定允许的那样。(通过linux x86-64函数调用保留哪些寄存器(

在为double a,b;保留堆栈空间之后,C等价物类似于scanf("%lf %lf", &b, &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.

对于一个堆栈插槽,伪推送/弹出通常只值得(而不是add rsp, imm8(,然后主要是如果您要立即使用call而不是显式引用RSP。这样做将插入一个堆栈同步uop。

相关内容

  • 没有找到相关文章

最新更新