c++ - 将 64 位 int 作为输出传递给 32 位内联汇编

标签 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;
}

转换为:

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

您可以看到它使用 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;
}

输出是:

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

现在您可以看到我必须手动将低位和高位放入两个单独的整数中。然后我执行移位将其变成一个 64 位整数。

有没有办法自动将其放入单个 64 位整数中,而无需我提供两个 32 位整数,然后进行移位?

最佳答案

您需要“A”约束,它将 64 位值绑定(bind)到 eax/edx 寄存器对。像这样的东西:

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

应该可以解决问题。

关于c++ - 将 64 位 int 作为输出传递给 32 位内联汇编,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27793396/

相关文章:

c++ - 使用 Boost 的 C++ 中的正则表达式

c - c 中是否有用于创建、删除或列出 btrfs 子卷的任何 BTRFS 库接口(interface)?

c++ - 为什么在 C++ 命名空间周围使用 extern "C"

c - 将动态大小的可变长度数组 (VLA) 初始化为 0

c++ - 如何控制QSplashscreen的定位?

c++ - 如何在模板中为类型引入名称别名

c++ - Win32 -- 如何管理我的鼠标钩子(Hook)线程

c++ - 在 Linux 中使用硬件性能计数器

c - 如何在 C 中针对各种大小的缓冲区测试 WKdm 算法

gcc - 将 GCC 的链接时优化与静态链接库一起使用