Search code examples
assemblyx86gnu-assembleratt

GAS Assembler operand type mismatch for `cmovz'


I am trying to write a simple assembly program. For some reason the conditional moves seem to give me this error. If I replace them with normal mov instruction it works. What is wrong with the following code?

    .section .data

supported:
    .asciz "AVX is supported"
notsupported:
    .asciz "AVX is not supported"


    .section .text
    .global main
main:
    movq $1, %rax
    cpuid
    andq $0x10000000, %rcx
    cmovnz $supported, %rdi
    cmovz $notsupported, %rdi
    callq puts

    movq $0, %rax
    ret
cpuid.S:15: Error: operand type mismatch for `cmovnz'
cpuid.S:16: Error: operand type mismatch for `cmovz'

Solution

  • If you look at the description of CMOVcc in Intel's manual you'll see that the source operand needs to be an r/m64 (i.e. a 64-bit register or memory location). $supported and $notsupported are immediates, and therefore do not qualify as an r/m64.

    You could do something like this:

    movabs $notsupported,%rdi
    movabs $supported,%rbx
    testq $0x10000000, %rcx   # checks the desired bit without clobbering %rcx
    cmovnz %rbx,%rdi