Danny
Danny

Reputation: 13

Error with gcc inline assembly

I'm trying to learn how to write gcc inline assembly.

The following code is supposed to perform an shl instruction and return the result.

#include <stdio.h>
#include <inttypes.h>

uint64_t rotate(uint64_t x, int b)
{
    int left = x;
    __asm__ ("shl %1, %0"
             :"=r"(left)
             :"i"(b), "0"(left));

   return left;
}

int main()
{
    uint64_t a = 1000000000;
    uint64_t res = rotate(a, 10);
    printf("%llu\n", res);
    return 0;
}

Compilation fails with error: impossible constraint in asm

The problem is basically with "i"(b). I've tried "o", "n", "m" among others but it still doesn't work. Either its this error or operand size mismatch.

What am I doing wrong?

Upvotes: 1

Views: 680

Answers (1)

David Wohlferd
David Wohlferd

Reputation: 7483

As written, you code compiles correctly for me (I have optimization enabled). However, I believe you may find this to be a bit better:

#include <stdio.h>
#include <inttypes.h>

uint64_t rotate(uint64_t x, int b)
{
    __asm__ ("shl %b[shift], %[value]"
             : [value] "+r"(x)
             : [shift] "Jc"(b)
             : "cc");

   return x;
}

int main(int argc, char *argv[])
{
    uint64_t a = 1000000000;
    uint64_t res = rotate(a, 10);
    printf("%llu\n", res);
    return 0;
}

Note that the 'J' is for 64bit. If you are using 32bit, 'I' is the correct value.

Other things of note:

  • You are truncating your rotate value from uint64_t to int? Are you compiling for 32bit code? I don't believe shl can do 64bit rotates when compiled as 32bit.
  • Allowing 'c' on the input constraint means you can use variable rotate amounts (ie not hard-coded at compile time).
  • Since shl modifies the flags, use "cc" to let the compiler know.
  • Using the [name] form makes the asm easier to read (IMO).
  • The %b is a modifier. See https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#i386Operandmodifiers

If you want to really get smart about inline asm, check out the latest gcc docs: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

Upvotes: 4

Related Questions