C宏 - 如何将整数值转换为字符串文字

时间:2016-11-14 14:40:06

标签: c gcc assembly c-preprocessor avr

是否可以将#defined 整数符号的值逐字插入到GCC(AVR Studio)中汇编部分的字符串文字中?

我希望在下面的asm()块内的字符串文字中将“LEDS”替换为48。

#define LEDS 48 //I only want ONE mention of this number in the source
int x = LEDS;   //I'm using the value directly too

void DrawFrame()
{
    asm(
    "ldi        R27, 0x00       \n\t"
    "ldi        R26, 0x00       \n\t"
    "ldi        R18, LEDS       \n\t" //<-- substitution needed here
...
}

但我希望编译器/汇编程序(在预处理程序完成它的工作之后)看到这个......

#define LEDS 48 //I only want ONE mention of this number in the source
int x = LEDS;   //I'm using the value directly too

void DrawFrame()
{
    asm(
    "ldi        R27, 0x00       \n\t"
    "ldi        R26, 0x00       \n\t"
    "ldi        R18, 48         \n\t" //<-- substitution needed here
...
}

到目前为止,我已经尝试了所有我能想到的宏观技巧(#stringification,arg替换,甚至包含各种值和双引号组合的#including文件等等。)

我完全不熟悉将AVR汇编代码内联到AVR Studio的GCC编译器中的魔力。

我试图避免在我的源代码中多次出现“48”文字,如果预处理器可以为我执行这个替换会很好。

编辑:这是针对微控制器固件项目的 - 只是为了让生活变得有趣,几乎没有空间可以添加新代码。

3 个答案:

答案 0 :(得分:46)

我认为在utils标题中有一个字符串化的宏是很好的:

#define STR_IMPL_(x) #x      //stringify argument
#define STR(x) STR_IMPL_(x)  //indirection to expand argument macros

然后你可以保持宏的数字并将其字符串化为现场:

#define LEDS 48 
int x = LEDS;   

void DrawFrame()
{
    asm(
    "ldi        R27, 0x00       \n\t"
    "ldi        R26, 0x00       \n\t"
    "ldi        R18, "STR(LEDS)"       \n\t"
...
}

以上预处理:

int x = 48;

void DrawFrame()
{
    asm(
    "ldi        R27, 0x00       \n\t"
    "ldi        R26, 0x00       \n\t"
    "ldi        R18, ""48""       \n\t"
...
}

依赖于相邻字符串文字被连接的事实。

答案 1 :(得分:14)

如果使用约束,则可以避免字符串化乱码:

#define LEDS 48

void DrawFrame()
{
    asm volatile(
    "ldi R18, %[leds]"
    : : [leds] "M" (LEDS) : "r18");
}

答案 2 :(得分:13)

您需要两个辅助宏才能工作。然后你可以利用自动字符串连接:

#define STR(x) #x
#define EXPAND(x) STR(x)

#define LEDS 48
int x = LEDS;

void DrawFrame()
{
    asm(
    "ldi        R27, 0x00       \n\t"
    "ldi        R26, 0x00       \n\t"
    "ldi        R18, " EXPAND(LEDS) "       \n\t"
...
}

使用两个宏的原因是第一个单独不会扩展传入的参数。

如果你刚刚这样做了:

printf("LEDS = " STR(LEDS) "\n");

它会扩展到:

printf("LEDS = " "LEDS" "\n");

EXPAND宏允许传入的参数也被替换。

那么这个:

printf("LEDS = " EXPAND(LEDS) "\n");

将扩展到:

printf("LEDS = " "48" "\n");