将64位int作为输出传递给32位内联asm

Bra*_*don 2 c c++ gcc inline-assembly

#include <stdarg.h>
#include <stdint.h>

uint64_t test_func(int n)
{
    return 9223372036854775805;
}


int main()
{
    uint64_t r = test_func(10);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

转换为:

test_func(int):
    push    ebp
    mov ebp, esp
    mov eax, -3
    mov edx, 2147483647
    pop ebp
    ret

main:
    push    ebp
    mov ebp, esp
    and esp, -8
    sub esp, 24
    mov DWORD PTR [esp], 10
    call    test_func(int)
    mov DWORD PTR [esp+16], eax
    mov DWORD PTR [esp+20], edx
    mov eax, 0
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

您可以看到它使用2个寄存器来存储该64位整数.但是,在C/C++代码中,它只是一个变量.

我试图在内联汇编中复制它,但我必须这样做:

#include <stdarg.h>
#include <stdint.h>

int64_t test_func(int n)
{
    return 9223372036854775805;
}


int main()
{
    int32_t rlow = 0, rhigh = 0;

    asm(
        "push $10\n"
        "\tcall %P2"
        : "=a"(rlow), "=d"(rhigh)
    : "i"(&test_func) : "memory");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

test_func(int):
    push    ebp
    mov ebp, esp
    mov eax, -3
    mov edx, 2147483647
    pop ebp
    ret
main:
    push    ebp
    mov ebp, esp
    sub esp, 16
    mov DWORD PTR [ebp-8], 0
    mov DWORD PTR [ebp-4], 0
    push $10
    call test_func(int)
    mov DWORD PTR [ebp-8], eax
    mov DWORD PTR [ebp-4], edx
    mov eax, 0
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

现在你可以看到我必须手动将低阶和高阶位分成两个独立的整数.然后我执行移位使其成为一个64位整数.

有没有办法自动将它放入一个64位整数,而不必为它提供两个32位整数然后移位?

Chr*_*odd 5

您需要"A"约束,它将64位值绑定到eax/edx寄存器对.就像是:

uint64_t r;
asm("push $10\n"
    "\tcall %P1"
    : "=A"(r) : "i"(&test_func) : "memory");
Run Code Online (Sandbox Code Playgroud)

应该做的伎俩.