问题描述:

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.

相关阅读:
Top