JB Enterprises

JB Enterprises - Johan Bezem

Interim Management & Consulting

JB Enterprises - Blog


Use of in-line assembler using 'asm' variants

Just a "small" post to expand on my most recent tweet. In-line assembler is quite a difficult topic, but unavoidable in most embedded environments. And the syntactic variants are more numerous than the bugs in your code.

For that reason I give a piece of advice: For each different assembler semantic, use a different macro. For an assembler function, use ASM_FN like this:
ASM_FN int MyAssemblerFunction(void)
{
...assembler instructions...
}
For an in-line assembler block, use ASM_BLOCK like this:
...
a += 4;
ASM_BLOCK volatile {
...assembler instructions...
};
And for single-line in-line assembler instructions use ASM_LINE like this:
...
a += 4;
ASM_LINE movb ax,0b00000010;
...

Now, all these uses will need to expand into the non-standard keyword asm for the compiler to process everything correctly. Many compilers accept different forms of the keyword, so you may use asm, __asm and __asm__ interchangeably. If you want to, you can take these three variants instead of the ASM_(FN|BLOCK|LINE) as I suggested.

The idea is to enable Lint to expand each of these three forms differently: The function containing only assembler instructions shall be ignored by Lint, but its prototype needs to be known. Therefore we need to enable the Lint keyword _ignore_init (the body of the function is seen as a form of “initialization”), and provide the options:
+rw(_ignore_init)
+dASM_FN=_ignore_init
The plus-sign in the second option prevents the definition in our code (to asm or one its variants) to override the Lint-specific definition. However, for ASM_BLOCK this replacement will not work, so we need a different replacement:
+rw(_up_to_brackets)
+dASM_BLOCK=_up_to_brackets
And the third form again needs a different replacement, since in this case, no brackets need be present at all:
+rw(_to_semi)
+dASM_LINE=_to_semi
With some other form of in-line assembler definition you might even need _to_eol, or one of the other gobblers. But make sure to use different macros for different syntactic usages of asm, so you have the chance to use different gobblers for all situations.

Happy Linting!

March 1st, 2009

Valid XHTML 1.0 Strict Valid CSS www.bezem.de: © 1999 – 2019 by Johan Bezem, all rights reserved.
This page was last updated on Tuesday, 2017-07-25 17:26.