lkamp
lkamp

Reputation: 183

Inline assembler: Pass a constant

I have the following problem: I want to use the following assembler code from my C source files using inline assembler:

.word 1

The closest I've gotten is using this inline assembler code:

asm(".word %0\n": : "i"(1));

However, this results in the following code in the generated assembler file:

.word #1

So I need a way to pass a constant that is known at compile time without adding the '#' in front of it. Is this possible using inline assembler?

Edit:

To make it more clear why I need this, this is how it will be used:

#define LABELS_PUT(b) asm(".word %0\n": : "i"((b)));

int func(void) {
    LABELS_PUT(1 + 2);

    return 0;
}

I can't use ".word 1" because the value will be different every time the macro LABELS_PUT is called.

Upvotes: 2

Views: 4782

Answers (2)

Mark Volt
Mark Volt

Reputation: 15

In GCC you can do it like this:

asm __volatile__ (".word 0x1");

If you are using Visual Studio then you can try:

some_word: _asm{_emit 1000b}

It will pass into code word constant 1000b

You can get access with label some_word

Upvotes: -1

Peter Cordes
Peter Cordes

Reputation: 363940

Your macro has a ; at the end. So it's a whole statement, not just an expression. Don't do that.

A .word mixed in with the code of your function is usually going to be an illegal instruction, isn't it? Are you actually planning to run this binary?


You should be able to get the preprocessor to stringify your macro parameter, and let string-concatenation join it up. Then the assembler can evaluate 1+2.

#define LABELS_PUT(b) asm(".word " #b  "\n")


LABELS_PUT(1+2);   // becomes:
asm(".word " "1+2" "\n");

There's also https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#x86Operandmodifiers, some of which might work for other architectures:

asm (".word %c0" : : "i" (b))

Upvotes: 4

Related Questions