Ole*_*leg 2 c++ x86 x86-64 inline-assembly clang++
我正在尝试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;
}
Run Code Online (Sandbox Code Playgroud)
您的代码过于复杂,似乎您可能已经在其他地方查看了编译器生成的代码来创建答案。
怎么b=++a;办?它首先递增a,然后将该值分配给b。在这样的表达式a中,既用作输入又用作输出。a读取的值,将其增加1,保存,并将结果复制到b。使用GCC的扩展内联汇编,您可以a使用约束上的+ 修饰符将其视为输入和输出操作数。可以与约束上的修饰符一起用于仅输出操作数。该指令可用于递增,该指令可用于复制该值。b=INCaMOVb
内联程序集可能看起来像:
#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;
}
Run Code Online (Sandbox Code Playgroud)
输出应为:
a = 1,b = 1
注意:由于除了寄存器我们没有告诉我们要修改的寄存器以外,没有其他副作用,因此不需要volatile在asm语句中使用它。
| 归档时间: |
|
| 查看次数: |
93 次 |
| 最近记录: |