EmbDev.net

Forum: ARM programming with GCC/GNU tools inline asm syntax question


Author: Tat Wan (Company: Universiti Sains Malaysia) (tcwan)
Posted on:

Rate this post
0 useful
not useful
Hi,

I'm trying to use #defines in inline assembly. However, I kept getting 
invalid syntax errors.

The following is hardcoded inline assembly:
inline void dbg_breakpoint_arm(void) { asm volatile (".word 0xE127FF7F" /* (BKPT32_INSTR | BKPT32_MANUAL_BKPT) */ ); }
which compiles fine in gcc.

When I write it as follows:
inline void dbg_breakpoint_arm(void) { asm volatile (".word %0" : "=i" (0xE127FF7F) /* (BKPT32_INSTR | BKPT32_MANUAL_BKPT) */ ); }

gcc gives the following errors (or some variant thereof, this may not be 
the exact error message for the above statement).
./armdebug/Debugger/debug_stub.h: In function 'dbg_breakpoint_arm':
./armdebug/Debugger/debug_stub.h:162:1: error: lvalue required in asm 
statement.

Is there a way for me to use constant #defines as operands for the asm 
statement? What is the correct gcc syntax?

TIA

Author: Stefan B. (stefan)
Posted on:

Rate this post
0 useful
not useful
Instead of
inline void dbg_breakpoint_arm(void) { asm volatile (".word %0" : "=i" (0xE127FF7F) /* (BKPT32_INSTR | BKPT32_MANUAL_BKPT) */ ); }

try
inline void dbg_breakpoint_arm(void) 
{ 
  asm volatile (".word %0" 
    :                  /* Output (empty) */
    : "i" (0xE127FF7F) /* (BKPT32_INSTR | BKPT32_MANUAL_BKPT) */ 
  ); 
}

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assemb...

Author: Tat Wan (Company: Universiti Sains Malaysia) (tcwan)
Posted on:

Rate this post
0 useful
not useful
@Stefan,

Thanks, I'm not familiar with inline assembly, the gcc reference manual 
was pretty cryptic and did not provide examples that explained things 
clearly (unfortunately I didn't come across the HOWTO before this).

I tried your suggestion, only change was to use the #defines (but it 
does not make any difference to the generated output).
inline void dbg_breakpoint_arm(void)
{
  asm volatile (".word %0"
                  :     /* Output (empty) */
                  : "i" /* (0xE127FF7F) */ (BKPT32_INSTR | BKPT32_MANUAL_BKPT)
               );
}


The assembly output file had:
        .word #-517472385

which results in "Error: bad expression."
If I remove the '#' manually from the assembly file it passes assembly 
stage without any syntax errors. It seems like the compiler expects 
operands to be passed to instructions (and hence prepends the '#' 
symbol) instead of being used as data values?

Author: Stefan B. (Guest)
Posted on:

Rate this post
0 useful
not useful
That is IMHO a puzzler and i found only one strange solution after a 
long search and a lot of trials. I'm not sure this solution is suitable 
for all arm-gcc versions. Mine is 4.1.1 (WinARM) and this works:

// I assume your defines look like these
#define BKPT32_INSTR        0xE1270000 // BKPT
#define BKPT32_MANUAL_BKPT  0x0000FF7F // Argument of BKPT

int main(void)
{
  asm volatile (".word %a0" : : "X" (BKPT32_INSTR | BKPT32_MANUAL_BKPT) );
}


The usage of modifier in %a0 is based on an old gcc manual
http://sunsite.ualberta.ca/Documentation/Gnu/gcc-2...

The c modifier from the same manual doesn't work at all.

Author: Stefan B. (Guest)
Posted on:

Rate this post
0 useful
not useful
ADD: Sorry, i wrote main() instead of inline void 
dbg_breakpoint_arm(void). This comes from the tests.

Author: Tat Wan (Company: Universiti Sains Malaysia) (tcwan)
Posted on:

Rate this post
0 useful
not useful
@Stefan,

Thanks! This works in gcc-4.5.1 as well.

T.C.

Author: Andreas B. (Guest)
Posted on:

Rate this post
0 useful
not useful
Why don't you simply use the BKPT instruction provided by the assembler 
instead of assembling it yourself?

Also, given that you probably intend to put the function definition in a 
header to inline it always, you should make it "static inline". 
Otherwise you'll get a "multiple definition" error when linking.

Author: Tat Wan (Company: Universiti Sains Malaysia) (tcwan)
Posted on:

Rate this post
0 useful
not useful
Hmm. I didn't know about the static inline issue. I'll do that.

I'm actually emulating BKPT on ARMv4T which does not support this 
instruction.
The hex value has to be tweaked as the actual BKPT instr value 0xE1xxx 
does not trigger on ARM7 CPU. I'm using 0xE7xxxx (Undef) which works.

T. C.

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.