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

我正在尝试使用内联汇编实现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 $0,-4(%%rbp);"
    "movl $0,-8(%%rbp);"
    "addq $1,-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;
}
xunying_1 回答:使用CLANG内联汇编创建C ++预增量操作

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

b=++a;的作用是什么?它首先递增a,然后将该值分配给b。在这样的表达式中,a既用作输入也用作输出。读取a的值,将其递增1,保存并将结果复制到b。使用GCC的extended inline assembly,您可以使用modifier上的a constraint+当作输入和输出操作数。 b可以与约束上的=修饰符一起用于仅输出操作数。 INC指令可用于递增a,而MOV指令可用于复制该值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


注意:由于除了寄存器告诉我们要修改的寄存器之外,没有其他副作用,因此不必在asm语句上使用volatile

本文链接:https://www.f2er.com/3064168.html

大家都在问