使用 CLANG 内联汇编创建 C++ 预增量操作

Creating a C++ pre-increment operation with CLANG inline assembly

我正在尝试使用内联汇编执行与 b = ++a; 等效的操作,但在执行代码后我的变量中出现了奇怪的值。我正在使用 clang++(g++ 兼容)来编译内联汇编。这是我到目前为止得到的:

#include <iostream>

using std::endl;
using std::cout;

int main()
{
    uint64_t a = 0;
    uint64_t b = 0;

    asm volatile(
    "pushq %%rbp;"
    "movq %%rsp, %%rbp;"
    "movl [=10=], -4(%%rbp);"
    "movl [=10=], -8(%%rbp);"
    "addq , -4(%%rbp);"
    "mov -4(%%rbp), %%rax;"
    "mov %%rax, -8(%%rbp);"
    "mov -4(%%rbp), %0;"
    "mov -8(%%rbp), %1;"
    "movq %%rbp, %%rsp;"
    "popq %%rbp"
    :"=r" (a), "=r" (b)
    :
    :"%rax", "%rbp", "%rsp"
    );
    cout << "a = " << a << ", b = " << b << endl;
    return 0;
}

您的代码过于复杂,看来您可能已经从其他地方查看了编译器生成的代码来创建答案。

b=++a; 是做什么的?它首先递增 a,然后将该值赋给 b。在这样的表达式中,a 既用作输入又用作输出。读取 a 的值,加 1,保存并将结果复制到 b。 GCC 的 extended inline assembly you can treat a as an input and output operand using the + modifier on the constraint. b can be used with an output only operand using the = modifier on the constraint. The INC 指令可用于增加 aMOV 指令复制该值 b.

内联汇编可以简单地看起来像:

#include <iostream>

using std::endl;
using std::cout;

int main()
{
    uint64_t a = 0;
    uint64_t b = 0;

    asm ("inc %0\n\t"
         "mov %0, %1"
         : "+r" (a), "=r" (b)
    );
    cout << "a = " << a << ", b = " << b << endl;
    return 0;
}

输出应该是:

a = 1, b = 1


注意:因为除了我们告诉编译器我们要修改的寄存器之外没有其他副作用,所以没有必要在[上使用volatile =26=]声明。