I'm trying to push an xmm register onto the stack in x86_64 C code using GCC-style inline assembly. I looked at the answer to this question and am using this code
int main(void) {asm volatile("subq 16, %rsp");
asm volatile("movdqu xmm0, xmmword ptr (%rsp)");
}
and when I compile it on OS X 10.10.2 with clang 6.0, I get the error error: unexpected token in argument list
, and a green arrow pointing to the ptr in the second asm line.
I change the code to
int main(void) {asm volatile("subq 16, %rsp");
asm volatile("movdqu xmm0, xmmword (%rsp)");
}
and it gives me error: invalid operand for instruction
. I've tried changing xmmword
to dqword
, to no avail, and I'm not sure what I'm doing wrong.
Thanks in advance.
There are (at least) two dialects of assembler for the x86: intel format and at&t format. It looks like you are trying to write code using intel format, but compiling using at&t.
Your code will compile with:
int main(void) {
asm volatile("subq 16, %rsp");
asm volatile("movdqu %xmm0, (%rsp)");
}
If you use the -masm=intel compile switch, you can also use this (which may look more familiar to you):
int main(void) {
asm volatile("sub rsp, 16");
asm volatile("movdqu xmmword ptr [rsp], xmm0");
}
That said, writing an asm block using multiple asm statements like this is a bad idea. gcc docs explicitly state:
Do not expect a sequence of asm statements to remain perfectly consecutive after compilation. If certain instructions need to remain consecutive in the output, put them in a single multi-instruction asm statement.
So perhaps something more like:
int main(void) {
asm volatile("subq 16, %rsp\n"
"movdqu %xmm0, (%rsp)");
}
Also, if you are going to be reading or updating variables, you should not be using basic asm, but instead use Extended. The docs there are very detailed and there are a number of samples.