Reputation: 85
I need to write a macro which needs to inline assembly
#define create_me(name) \
__asm\
mov name,#0x1021\
__endasm\
The # however isn't compiling. I have tried passing it in as a parameter however that doesn't work too. It says invalid preprocessor token . I can try to use an inline function but I can't dynamically create the register name. That is I don't have access to the name variable. Does anyone have any suggestions on how to use the # operation inside a macro.
I have looked at Escaping a # symbol in a #define macro?, but I have clearly explained why I need the macro here. My usecase is different.
Upvotes: 3
Views: 3338
Reputation: 181689
It helps to understand the nature of the problem. The #
symbol is special to the preprocessor in three ways:
A source line whose first preprocessing token is #
is recognized by the preprocessor as not being a "text line". That is, it contains instructions for the preprocessor. Text lines, on the other hand, are the data to be processed -- mostly C program source, but possibly containing macros to be expanded. The #
is not special in this sense if it is not the first preprocessing token on the line.
Among the preprocessing tokens of the replacement list for a function-like macro, the token #
is the stringification operator. It does not serve that purpose in a variable-like macro, however, nor when macro-expanded text is re-scanned for further macro replacement.
Among the preprocessing tokens of the replacement list for a function-like macro, the token ##
is the token-pasting operator. It does not serve that purpose in a variable-like macro, however, nor when macro-expanded text is re-scanned for further macro replacement.
You cannot escape the significance of the #
to the preprocessor per se, but you can nevertheless implement your desired macro by employing a bit of indirection, as @Quentin demonstrated. In the first place, if a #
is to appear in the expansion of a function-like macro then it cannot appear directly in that macro's replacement text, where it would be interpreted as the stringification operator. It must instead be introduced by expanding another macro. In the second place, if it must abut other text without whitespace between, then the immediate macro that expands to it must be a function-like macro itself, so that the parentheses serve to separate the macro name from the abutting text. That requires a second level of indirection.
Upvotes: 0
Reputation: 120079
For SDCC, use the new __asm__
format.
#define create_me(name) \
__asm__( "mov " #name ", #0x1021" )
Upvotes: 2
Reputation: 63154
Using an indirection through another macro should do the trick:
#define HASH_LIT #
#define HASH() HASH_LIT
#define create_me(name) \
__asm\
mov name,HASH()0x1021\
__endasm
Upvotes: 6
Reputation: 41045
Preprocessor commands/directives always begin with a sharp sign (#
), you can not use it for your own symbols.
If you want to create a variable named whatever0x1021
use the token concatenation ##
:
#include <stdio.h>
#define create_me(name) name ## 0x121
int main(void)
{
int create_me(a); /* int a0x121; */
return 0;
}
Upvotes: 0