Search code examples
cgccx86inline-assemblyatt

c inline assembly getting "operand size mismatch" when using cmpxchg


I'm trying to use cmpxchg with inline assembly through c. This is my code:

static inline int
cas(volatile void* addr, int expected, int newval) {
    int ret;
    asm volatile("movl %2 , %%eax\n\t"
                "lock; cmpxchg %0, %3\n\t"
                "pushfl\n\t"
                "popl %1\n\t"
                "and $0x0040, %1\n\t"
                : "+m" (*(int*)addr), "=r" (ret)
                : "r" (expected), "r" (newval)
                : "%eax"
                );
    return ret;
}

This is my first time using inline and i'm not sure what could be causing this problem. I tried "cmpxchgl" as well, but still nothing. Also tried removing the lock. I get "operand size mismatch". I think maybe it has something to do with the casting i do to addr, but i'm unsure. I try and exchange int for int, so don't really understand why there would be a size mismatch. This is using AT&T style. Thanks


Solution

  • You had the operand order for the cmpxchg instruction is reversed. AT&T syntax needs the memory destination last:

        "lock; cmpxchg %3, %0\n\t"
    

    Or you could compile that instruction with its original order using -masm=intel, but the rest of your code is AT&T syntax and ordering so that's not the right answer.


    As far as why it says "operand size mismatch", I can only say that that appears to be an assembler bug, in that it uses the wrong message.