Invalid operand for instruction movq using clang

2019-07-28 07:23发布

问题:

I'm using the movq X86_64 assembly instruction on an Intel Core i5 with the LLVM-based clang-902.0.39.1 compiler.

The simplified code (at the my_asm.S file) in Intel syntax looks like this:

.intel_syntax noprefix

#define a_const   0xFFFFFFFFFFFFFFFF

movq   rax, a_const

I'm compiling with

clang -c -g -O3 -fwrapv -fomit-frame-pointer -march=native my_asm.S

The compiler gives me the following message:

error: invalid operand for instruction
movq rax, 0xFFFFFFFFFFFFFFFF
^

I've also tried the AT&T syntax as suggested in the comments:

movq   $a_const, %rax

which gives the error

error: unknown token in expression
movq $0xFFFFFFFFFFFFFFFF, %rax
^

This instruction was used to work for Intel syntax since I included the .intel_syntax noprefix flag in the beginning of my .S file. It seems that the error message started showing up after I updated my Mac OS (which updated the LLVM compiler, linker and Make).

Does anyone have a clue on what might be causing this?

回答1:

Works for me in AT&T syntax with mov $-1, %rax or mov $0xFFFFFFFFFFFFFFFF, %rax, or with movq instead of leaving operand-size implicit.

In Intel syntax, you can no longer use an operand-size q suffix to set the operand-size; it's implied by the register or with a qword ptr override on a memory operand.

movq is the mnemonic for instructions like movq xmm0, rax or movq xmm0, xmm1 (two separate opcodes / instruction set manual entries that both use the movq mnemonic, one being the REX form of movd xmm, r/m32, and the other being the xmm/mmx movq xmm, xmm/m64)

mov    $-1, %rax
mov    $0xFFFFFFFFFFFFFFFF, %rax

.intel_syntax noprefix
mov    rax, -1
mov    rax, 0xFFFFFFFFFFFFFFFF

assembles just fine with clang -c, to 4 copies of the same instruction:

0:   48 c7 c0 ff ff ff ff    mov    rax,0xffffffffffffffff

Note that -f... and -O3 code-gen options have no effect when only assembling, not compiling C/C++, nor does -march=native. Clang's assembler doesn't restrict instruction choice based on -march; it only sets what the compiler's code-gen will target. (None of the options you gave hurts, but they have no effect with a .S except for maybe -g.)