gpt4 book ai didi

c++ - 内联 gcc 程序集和局部变量(双)

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:49:56 26 4
gpt4 key购买 nike

我正在尝试使用 gcc/g++ 的内联 asm 指令(我不得不说我之前一直在 MSVC 上使用 Intel 语法,那是微风)。我正在玩弄 double 值,以下 my_func2 似乎在执行后崩溃:

  #include <iostream>

void my_func(const double *in, double *out) {
asm("mov %0, %%r8" : : "r"(in));
asm("movupd (%%r8), %%xmm0" :);
asm("movupd (%%r8), %%xmm1" :);
asm("addpd %%xmm1, %%xmm0" :);
asm("movupd %%xmm0, (%0)" : : "r"(out) : "%r8", "%xmm0", "%xmm1");
}

double my_func2(const double *in) {
double ret = 0.0;

asm("mov %0, %%r8" : : "r"(in));
asm("movupd (%%r8), %%xmm0" :);
asm("movupd (%%r8), %%xmm1" :);
asm("addpd %%xmm1, %%xmm0" :);
asm("movupd %%xmm0, %0" : "=m"(ret) : : "memory", "%r8", "%xmm0", "%xmm1");

return ret;
}

int main(int argc, char *argv[]) {
const double a = 1.0;
double b = 0.0;
my_func(&a, &b);
std::cout << "b:" << b << std::endl;
b = my_func2(&a);
std::cout << "b:" << b << std::endl;
}

我得到的错误具体是(当我使用 gdb 运行时):

Program received signal SIGBUS, Bus error.0x00000000004008e1 in main (argc=<error reading variable: Cannot access memory at address 0x400fffffffffffec>,     argv=<error reading variable: Cannot access memory at address 0x400fffffffffffe0>) at asm_test.cpp:2828      b = my_func2(&a);

我做错了什么?在 my_func2 的最后一行,我指定 memory 也被破坏了,我不明白......我在哪里可以找到如何使用臭名昭著的 AT&T 语法的好指南?
我编译:g++ -g -o asm_test asm_test.cpp, g++ version g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 在 Ubuntu 上 Linux scv 3.2.0-48-generic#74-Ubuntu SMP Thu Jun 6 19:43:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

我找到了 http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.htmlhttp://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html ,您有什么更多可以推荐的吗?

谢谢,
艾玛

最佳答案

这里的错误是在使用movupd 时必须小心。使用此指令,您实际上复制了 128 位内存,

碰巧第一个函数也可以复制这些值,但第二个函数在 ret 变量中只有 64 位空间。正如预期的那样,这会破坏堆栈,产生未定义的行为?
movupd 替换为 movlpd(或 movhpd),效果很有魅力

我还在破坏正确的寄存器吗?

当使用 g++ -O3 -o asm_test asm_test.cpp

编译时,以下代码 很好
  void my_func(const double *in, double *out) {
asm ("mov %0, %%r8" : : "r"(in));
asm ("movhpd (%%r8), %%xmm0" :);
asm ("movhpd (%%r8), %%xmm1" :);
asm ("addpd %%xmm1, %%xmm0" :);
asm ("movhpd %%xmm0, (%0)" : : "r"(out) : "memory", "%r8", "%xmm0", "%xmm1");
}

double my_func2(const double *in) {
double ret;

asm("mov %0, %%r8" : : "r"(in));
asm("movlpd (%%r8), %%xmm0" :);
asm("movlpd (%%r8), %%xmm1" :);
asm("addpd %%xmm1, %%xmm0" :);
asm("movlpd %%xmm0, %0" : "=m"(ret) : : "memory", "%r8", "%xmm0", "%xmm1");

return ret;
}

关于c++ - 内联 gcc 程序集和局部变量(双),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17519577/

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