简体   繁体   中英

How to use a macro in linux C inline assembly

I want to call an address that is determined by other configuration result. And that call is in an inline assembly.

Currently, it's like this and is manually modified:

asm volatile ("call 0xc0200c20\n\t");

My question is can I write it like this?

#define CALL_ADDR 0xC0200c20

asm volatile ("call CALL_ADDR\n\t");

Thanks!

Just ordinary string concatenation should do the trick, with two wrapper macros to create a stringified version of the value:

#define QUAUX(X) #X
#define QU(X) QUAUX(X)

asm volatile ("call " QU(CALL_ADDR) "\n\t");

Promoting my comment to an answer:

The P modifier for gcc's inline assembly operands stops the compiler from emitting 'constant-indicating prefixes' in the generated assembly code. See the linked reference for a more verbose explanation, quoting Linus.

If you've tried:

#define CALL_ADDR 12345678
asm volatile("call %0\n\t" :: "i"(CALL_ADDR));

you noticed you get an error from the assembler, because the generated code says call $12345678 and that's not valid assembly syntax. Using %P0 instead makes the compiler not emit the $ at the beginning, and it's fine.

There's no need to work with preprocessor string concatenation here - the disadvantage of that is, as you've found, that "nesting" (two levels of macros) is needed so that the CALL_ADDR is expanded before the concatenation is done.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM