多行内联汇编宏与字符串

时间:2013-06-23 10:16:33

标签: c gcc assembly inline-assembly c-preprocessor

我正在尝试实现一个宏("MY_MACRO"),它在某个部分("my_section")中存储一个前面带有32位整数的字符串。 示例:MY_MACRO(200, "my first string %u %x");

以下是我尝试的选项和我面临的问题。我将不胜感激任何帮助。 (gcc 4.7.3. MIPS cpu

选项A:

#define MY_MACRO(_num, _string)\
asm volatile(".pushsection .my_section");\
asm volatile(".byte %0, %1, %2, %3" : : "i"((_num >> 24) & 0xFF), "i"((_num >> 16) & 0xFF), "i"((_num >> 8) & 0xFF), "i"(_num & 0xFF)); /* Store the number */ \
asm volatile(".ascii " #_string);\
asm volatile(".popsection");

编译错误(每次使用宏时都不会出现):

c:\Temp\ccpDEDnt.s: Assembler messages:
c:\Temp\ccpDEDnt.s:1024: Warning: .popsection without corresponding .pushsection; ignored

我认为原因是编译器优化会改变指令顺序(虽然每个asm指令都是易失性的,但允许编译器更改顺序)。 问:有没有办法在没有#pragma的情况下仅针对这些行的范围禁用编译器优化? 这个问题让我找到了一个解决方案,其中统一了四个asm指令。


选项B:

#define MY_MACRO(_num, _string)\
asm volatile(".pushsection .my_section\n\t" \
             ".byte %0, %1, %2, %3\n\t" \
             ".ascii " #_string "\n\t" \
             ".popsection" \
             : : "i"((_num >> 24) & 0xFF), "i"((_num >> 16) & 0xFF), "i"((_num >> 8) & 0xFF), "i"(_num & 0xFF));

编译器错误:

foo.c:733:13: error: invalid 'asm': operand number missing after %-letter
foo.c:733:13: error: invalid 'asm': operand number out of range

由于字符串包含百分号(%),编译器会将其解释为asm操作数。


选项C:

#define MY_MACRO(_num, _string)\
asm volatile(".pushsection .my_section\n\t" \
             ".byte %0, %1, %2, %3\n\t" \
             ".ascii %4\n\t" \
             ".popsection" \
             : : "i"((_num >> 24) & 0xFF), "i"((_num >> 16) & 0xFF), "i"((_num >> 8) & 0xFF), "i"(_num & 0xFF), "X"(#_string));

这里我尝试将字符串作为操作数传递。我甚至不知道它是否可行。 我没有设法编译这段代码。

1 个答案:

答案 0 :(得分:0)

选项B 是正确的方法,但是您需要将字符串中出现的所有百分号(%)加倍,因为它被解释为内联asm中的操作数占位符。< / p>

如果您不特别关心订购或内联,也可以让gcc为您处理:

struct mystruct
{
    int num;
    char string[0];
};

#define MY_MACRO(_num, _string)\
{ static struct mystruct entry __attribute__ ((section (".my_section"))) = { _num, _string }; }