将 xmm 寄存器推入堆栈时出错
Posted
技术标签:
【中文标题】将 xmm 寄存器推入堆栈时出错【英文标题】:errors when pushing xmm registers onto stack 【发布时间】:2015-03-18 01:56:56 【问题描述】:我正在尝试使用 GCC 样式的内联汇编在 x86_64 C 代码中将 xmm 寄存器推送到堆栈中。我查看了this 问题的答案并正在使用此代码
int main(void)
asm volatile("subq 16, %rsp");
asm volatile("movdqu xmm0, xmmword ptr (%rsp)");
当我在 OS X 10.10.2 上使用 clang 6.0 编译它时,我收到错误 error: unexpected token in argument list
,并且在第二个 asm 行中有一个指向 ptr 的绿色箭头。
我把代码改成
int main(void)
asm volatile("subq 16, %rsp");
asm volatile("movdqu xmm0, xmmword (%rsp)");
它给了我error: invalid operand for instruction
。我尝试将xmmword
更改为dqword
,但无济于事,我不确定自己做错了什么。
提前致谢。
【问题讨论】:
你不能在不混淆编译器的情况下从内联汇编修改rsp
。你也can't tell the compiler you're clobbering the red-zone, so you can't use the stack unless you skip the first 128b。如果您想在 inline-asm 中使用向量 reg,只需在其上声明一个 clobber,而不是自己保存/恢复它。
【参考方案1】:
x86 有(至少)两种汇编语言方言:intel 格式和 at&t 格式。看起来您正在尝试使用 intel 格式编写代码,但使用 at&t 进行编译。
您的代码将编译为:
int main(void)
asm volatile("subq 16, %rsp");
asm volatile("movdqu %xmm0, (%rsp)");
如果您使用 -masm=intel 编译开关,您也可以使用它(您可能看起来更熟悉):
int main(void)
asm volatile("sub rsp, 16");
asm volatile("movdqu xmmword ptr [rsp], xmm0");
也就是说,像这样使用多个 asm 语句编写一个 asm 块是个坏主意。 gcc 文档明确state:
不要期望一系列 asm 语句在编译后保持完全连续。如果某些指令需要在输出中保持连续,请将它们放在单个多指令 asm 语句中。
所以也许更像:
int main(void)
asm volatile("subq 16, %rsp\n"
"movdqu %xmm0, (%rsp)");
另外,如果您要读取或更新变量,则不应使用basic asm,而应使用Extended。那里的文档非常详细,并且有许多示例。
【讨论】:
以上是关于将 xmm 寄存器推入堆栈时出错的主要内容,如果未能解决你的问题,请参考以下文章