'Expected ')' before token inline assembly error

I would like to learn some inline assembly programming, but my first cod snippet does not work. I have a string and I would like to assign the value of the string to the rsi register.

Here is my code:

    string s = "Hello world";
    const char *ystr = s.c_str();
    asm("mov %1,%%rsi"
    :"S"(ystr)
    :"%rsi" //clobbered register
);

    return 0;

It gives me the error :Expected ')' before token. Any help is appreciated.



Solution 1:[1]

You left out a : to delimit the empty outputs section. So "S"(ystr) is an input operand in the outputs section, and "%rsi" is in the inputs section, not clobbers.

But as an input it's missing the (var_name) part of the "constraint"(var_name) syntax. So that's a syntax error, as well as a semantic error. That's the immediate source of the error <source>:9:5: error: expected '(' before ')' token. https://godbolt.org/z/97aTdjE8K


As Nate pointed out, you have several other errors, like trying to force the input to pick RSI with "S".

   char *output;   // could be a dummy var if you don't actually need it.
   asm("mov %1, %0"
     : "=r" (output)     /// compiler picks a reg for you to write to.
    :"S"(ystr)           // force RSI input
    :   // no clobbers
   );

Note that this does not tell the compiler that you read or write the pointed-to memory, so it's only safe for something like this, which copies the address around but doesn't expect to read or write the pointed-to data.

Also related:

Solution 2:[2]

In general, when using gcc inline asm on x86, you want to avoid ever using mov instructions, and want to avoid explicit registers in the asm code -- just use the register constraints to get things in the appropriate registers. So for your example, getting a string pointer into the rsi register, you want just:

asm volatile("; ystr wil be in %rsi here"
            :  // no output contraints
            : "S"(ystr)  // input constraint
            :  // no clobber needed
            );

Note that there's no actual asm code output here -- just a comment. The input constraint is sufficient to get the operand into the needed register prior to the point where this appears. Yes, rsi might well be used for something else afterwards, but that is as expected -- the register constraints just cover the inputs and outputs of the asm text.

Solution 3:[3]

In my case, C++ code was compiled with -std=c++17 and the compiler also reported expected ')' before ':' token

I changed the keyword asm to __asm__ and in my case, this helped.

This modification was inspired by "When writing code that can be compiled with -ansi and the various -std options, use __asm__ instead of asm" from https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html, however as commented below, this may not be completely precise.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Peter Cordes
Solution 2 Chris Dodd
Solution 3