c++ - 使用 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;
}
解决方案
您的代码过于复杂,看来您可能已经从其他地方查看了编译器生成的代码来创建答案。
做什么b=++a;
?它首先递增a
,然后将该值分配给b
. 在这样的表达式a
中,既用作输入又用作输出。读取的值a
,加 1,保存并将结果复制到b
。使用 GCC 的扩展内联汇编,您可以使用约束上的修饰符a
将其视为输入和输出操作数。可以使用约束上的修饰符与仅输出操作数一起使用。该指令可用于递增和复制该值的指令。+
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
注意:由于除了我们告诉编译器我们要修改的寄存器之外没有其他副作用,因此没有必要volatile
在asm
语句上使用。
推荐阅读
- ios - 注销并登录后 TableView 未正确更新
- html - 为什么视图不读取
元素? - vue.js - 如何将 css 样式传递给 Vue 中的插件?
- sass - 如果条件需要您的 SCSS 帮助
- react-native - 如何动态显示不同卡片中的多个数据。在本机反应
- javascript - PHP json 到 HTML 文件中的 JavaScript 变量
- json - Microsoft Sharepoint 中的列格式
- conda - 旧版本的 conda 安装包
- c++ - 使用move构造函数的push_back不调用析构函数?
- html - CSS Flexbox - 响应式边距