如何在程序集中访问scanf调用的第一个参数?

问题描述 投票:0回答:1

说我在(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调用约定,但尚未找到明确的答案。

assembly scanf x86-64 nasm calling-convention
1个回答
1
投票

%lfdouble,而不是单精度float。不,要传递给scanf的2个参数是double *not double,因此您应该将AL=0设置为2

无论如何,您的问题是您为两个输出操作数传递了相同的指针。 并且那个scanf破坏了它的arg传递寄存器,就像调用约定允许的那样。What registers are preserved through a linux x86-64 function call

scanf("%lf %lf", &b, &b)保留堆栈空间后,C等效项类似于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.
对于[[one堆栈插槽,通常仅使用[[虚拟推入/弹出](而不是add rsp, imm8),然后如果您要立即进入call而不是明确引用RSP,则通常才值得。这样做将插入堆栈同步uop。
© www.soinside.com 2019 - 2024. All rights reserved.