问题
I'm trying to implement a macro ("MY_MACRO"
), which stores a string preceded by a 32 bit integer number in a certain section ("my_section")
.
Example: MY_MACRO(200, "my first string %u %x")
;
Here are the options I tried and the problems I'm facing with. I would appreciate any help.
(gcc 4.7.3. MIPS cpu
)
Option 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");
Compile error (it doesn't occur for each usage of the macro):
c:\Temp\ccpDEDnt.s: Assembler messages:
c:\Temp\ccpDEDnt.s:1024: Warning: .popsection without corresponding .pushsection; ignored
I think the reason is a compiler optimization which changes the instructions order (although each asm instruction is volatile, the compiler is allowed to change the order).
Q: Is there any way to disable the compiler optimizations just for the scope of these lines without #pragma
?
This issue led me to find a solution in which the four asm instructions are unified.
Option 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));
Compiler errors:
foo.c:733:13: error: invalid 'asm': operand number missing after %-letter
foo.c:733:13: error: invalid 'asm': operand number out of range
Since the string includes the percent sign (%), the compiler interprets it as an asm operands.
Option 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));
Here I tried to pass the string as an operand. I don't even know if it's feasible. I didn't manage to compile this code.
回答1:
Option B is the right way, however you will need to double all percent signs (%
) occurring in your string because that's interpreted as an operand placeholder in the inline asm.
If you don't particularly care about ordering or inlining, you could also let gcc
handle it for you:
struct mystruct
{
int num;
char string[0];
};
#define MY_MACRO(_num, _string)\
{ static struct mystruct entry __attribute__ ((section (".my_section"))) = { _num, _string }; }
来源:https://stackoverflow.com/questions/17259732/multi-line-inline-assembly-macro-with-strings