0

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.

Community
  • 1
  • 1
Jack Maloney
  • 527
  • 2
  • 5
  • 18
  • You can't modify `rsp` from inline asm without confusing the compiler. You also [can't tell the compiler you're clobbering the red-zone, so you can't use the stack unless you skip the first 128b](https://stackoverflow.com/questions/34520013/using-base-pointer-register-in-c-inline-asm/34522750#34522750). If you want to use a vector reg in inline-asm, just declare a clobber on it instead of save/restoring it yourself. – Peter Cordes Nov 13 '17 at 02:23

1 Answers1

1

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.

David Wohlferd
  • 7,110
  • 2
  • 29
  • 56