【发布时间】:2015-06-02 01:58:24
【问题描述】:
我正在考虑提高我编写和分析的 C++ 库的运行时性能。我对汇编(和内联汇编)非常陌生,并且有一个非常基本的问题要问。
如何使用内联汇编将 xmm 寄存器(xmm、ymm、zmm 等)的值设置为常量浮点值或双精度值?我强烈不喜欢使用 GCC 的扩展程序集来使代码更容易移植到 MSVC。使用 -S 编译时,我看到 GCC 使用了 .data 部分,但是,我认为我不能在内联代码中使用它。
为简单起见,假设我想在以下 C 代码中实现 foo 函数:
#include <cstdio>
void foo(double *val);
int main(int argc, char **argv) {
double val = 0.0;
foo(&val);
printf("val: %lf\n", val);
return 0;
}
void foo(double *val) {
// return *val + 1.0.
__asm__ (
"movq -8(%rbp), %rax\n\t" // move pointer from stack to rax.
"movq (%rax), %xmm1\n\t" // dereference pointer and move to xmm1.
"?????????????" // somehow move 1.0 to xmm0.
"addsd %xmm1, %xmm0\n\t" // add xmm1 to xmm0.
"movsd %xmm0, (%rax)\n\t" // move result back val.
);
}
我尝试使用push $0x3ff0000000000000 和pushq $0x3ff0000000000000 将值移动到堆栈,然后可能将其移动到xmm0,结果如下:
"pushq $0x3ff0000000000000\n\t" = "错误:`push' 的操作数类型不匹配"。
"push $0x3ff00000\n\t" = 这条指令的分段错误。
我们将不胜感激,并提前感谢您的宝贵时间。
【问题讨论】:
-
我看到了那个帖子,但它在声明
const1: dq 1.2345时仍然使用.data部分,我无法在内联汇编中访问它。除非我误解了某些东西(这很可能)。不过感谢您的回复。 -
尝试阅读第一条回复:stackoverflow.com/a/6514824/2702398
-
你指的是
push的建议吗?还是使用扩展程序集的那个? - 我试图避免扩展组装,push会导致段错误。 -
push - 这就是 C 编译器的工作方式。