CARM User's Guide

Discontinued

Use in Macro Definitions

C macros provide a convenient way to insert extended inline assembly code into your C source code. Macros demand extra care because they expand in a single logical line. Follow these rules to create trouble-free macros:

  • Enclose the __asm block in braces ('{}').
  • Put the __asm keyword in front of each assembly instruction.
  • Use only traditional C comment delimiters ('/*') and ('*/'). Assembly-style comment delimiters (';') and single-line C comment delimiters ('//') are not possible.

For example:

#define ABLOCK __asm  {  /* comment */              \ 
                       __asm       add  R5,R5,#0x1  \ 
                       __asm   l1: ldr Rl,='}'      \ 
                       __asm       ands R5,R4,#0x10 \ 
                       __asm       beq  l1          \ 
                      }

The __asm keywords (highlighted in red) seem superfluous. However, they are required because C macros are expanded in a single line.

The preprocessor's handling of '#' within macro definitions that begin with the __asm keyword is relaxed (since # is used for immediate values in assembly language). In standard C, an assembly immediate value like #0x10 would cause an error in the preprocessor phase because it violated the C preprocessor rules.

The following example demonstrates how to define and use an extended inline assembly block in a macro.

#define ABLOCK __asm  {  /* comment */              \ 
                       __asm       add  R5,R5,#0x1  \ 
                       __asm   l1: ldr  Rl,='}'     \ 
                       __asm       ands R5,R4,#0x10 \ 
                       __asm       beq  l1          \ 
                      }

int  i;

void main (void)  {
  i = 1;
  ABLOCK        // expand inline assembly macro
  i = 2;
}

The following example defines a macro that accesses a variable from inline assembly code.

#define PR1()  {                                         \ 
                extern volatile unsigned int ulCritical; \ 
                __asm  { LDR  R1,=ulCritical };          \ 
                __asm  { LDR  R0,[R1]        };          \ 
                }