gpt4 book ai didi

C++ 多线程内联汇编

转载 作者:行者123 更新时间:2023-11-28 05:54:37 24 4
gpt4 key购买 nike

我想在一个线程中运行内联 asm,但我在某些指令上遇到了段错误,如下所示:

#include <thread>

void Foo(int &x)
{
int temp;
asm volatile ("movl $5, %%edx;"
"movl $3, %%eax;"
"addl %%edx, %%eax;"
"movl %%eax, -24(%%rbp);" // seg faults here
"movl -24(%%rbp), %0;"
: "=r" (temp) : : );
x=temp;
}

int main()
{
int x;
std::thread t1(Foo, std::ref(x));
t1.join();
return 0;
}

(我正在使用 std::ref 来传递对 std::thread 的引用,但必须使用 temp 变量,因为扩展的 asm 语法不适用于引用。)

我已经尝试破坏所有涉及的寄存器,但没有帮助。如果我不向线程传递任何参数,它似乎可以工作:而且奇怪的是,如果我破坏 %ebx 寄存器(不涉及),它也可以工作。我在 64 位 Ubuntu 14.04 上使用 gcc 4.8.4。

在线程中执行内联 asm 的最佳/最安全方法是什么?

最佳答案

我仍然不完全相信我理解您的目标是什么。我发现评论“但必须使用临时变量,因为扩展的 asm 语法不适用于引用。”有点不寻常。我希望您可以将引用传递给汇编程序模板,因为它实际上只是一个指针。由于您使用的是人为设计的示例,因此我将保留该示例,但不包括将数据移动到堆栈上的任意位置,并且我会将被破坏的寄存器添加到列表中。你可能会选择类似的东西:

#include <thread>

void Foo(int &x)
{
asm volatile ("movl $5, %%edx;" // We clobber EDX
"movl $3, %%eax;" // We clobber EAX
"addl %%edx, %%eax;" // Result in EAX=3+5=8
"movl %%eax, %0;" // Move to variable x
: "=r" (x) : : "eax", "edx" );
}

int main()
{
int x;
std::thread t1(Foo, std::ref(x));
t1.join();
return 0;
}

我已将 "eax""edx" 添加到 clobber 列表中,因为我们在汇编程序模板中销毁了它们(并且它们不显示为输入或输出约束)。您还应该注意到我没有使用临时变量。汇编代码可以简化为一条指令,因为人为设计的示例等同于 movl $8, %0;

你也可以像这样使用x的内存地址(引用):

void Foo(int &x) 
{
asm volatile ("movl $5, %%edx;" // We clobber EDX
"movl $3, %%eax;" // We clobber EAX
"addl %%edx, %%eax;" // Result in EAX=3+5=8
"movl %%eax, %0;" // Move to variable x
: "=mr" (x) : : "eax", "edx" );
}

在这种情况下,我使用 =mr(内存操作数或寄存器)作为输出约束。这使我们能够在没有中间寄存器的情况下将值直接移动到内存操作数。

关于C++ 多线程内联汇编,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34457866/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com