将xmm寄存器推入堆栈时出错

时间:2015-03-18 01:56:57

标签: c inline-assembly sse

我尝试使用GCC样式的内联汇编将xmm寄存器压入x86_64 C代码中的堆栈。我查看了this问题的答案并使用了此代码

int main(void) {
    asm volatile("subq 16, %rsp");
    asm volatile("movdqu xmm0, xmmword ptr (%rsp)");
}

当我使用clang 6.0在OS X 10.10.2上编译它时,我得到错误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,但无济于事,而且我不确定自己做错了什么。

提前致谢。

1 个答案:

答案 0 :(得分:1)

对于x86:intel格式和& t格式,有(至少)两种汇编语言。看起来您正在尝试使用英特尔格式编写代码,但使用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 docs明确state

编译后,不要指望asm语句序列保持完全连续。如果某些指令需要在输出中保持连续,请将它们放在单个多指令asm语句中。

所以也许更像是:

int main(void) {
    asm volatile("subq 16, %rsp\n"
                 "movdqu %xmm0, (%rsp)");
}

此外,如果您要阅读或更新变量,则不应使用basic asm,而应使用Extended。那里的文档非常详细,有很多样本。