Using Assember Macros in C

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using Assember Macros in C

3,970 Views
Deadstar
Contributor I
Hey guys,

First of all excuse me if this is in the wrong section, I think I am OK though.

I am writing a C programme on the HCS12 but need to use some assembler in it. I am using the __asm{}.

The assembler I need to input is a bit repetitive, i.e using the same statements again. I understand macros can be used to reduce the code written.

Two questions:

Can I use macros when I am embedding assembler in C and if so where can I put it?
Are there any extra clock cycles added on using macros instead of just writing the code?

Regards,

Colin
Labels (1)
Tags (1)
0 Kudos
7 Replies

1,105 Views
CompilerGuru
NXP Employee
NXP Employee
Macros in C are just replacing text, so they can  be used for any kind of tasks in C.
With respect to HLI and macros there are two traps to look out for.
- macros expand to a single source code line, but the __asm{} syntax is using end of line for each instruction, so that does not mix. Instead with macros use the __asm nop; syntax:
#define ONE_NOP __asm nop;

The second issue is with the # character, that one has a specific meaning to the preprocessor. If your HLI code contains #, then the C language meaning has to be disabled, there is a pragma for it. E.g.

#pragma NO_STRING_CONSTR
#define LOAD_0 LDD #0

Daniel



0 Kudos

1,105 Views
Lundin
Senior Contributor IV
That code isn't portable though. The # symbol is a perfect argument of why macros shouldn't be used for inline assembler. And there are loads of other issues with macros.

My advise is to stay away from the pre-processor and write functions instead. That will also make the code way more readable. And if performance is critical, use inline functions. CW supports it even for "classic" C.

#pragma INLINE
void one_nop (void)
{
  __asm NOP;
}
0 Kudos

1,105 Views
CompilerGuru
NXP Employee
NXP Employee
Well, if there are portability concerns, then those do rule out the use of inline assembly in the first placeI would assume.
So for simple tasks like adding a nop ( :smileywink: ) enabling interrupt I consider using HLI directly (or via macro) is fine. There are also cases where using inlined HLI functions generates more code or is not even possible, say when the HLI code has to access arguments, or when it includes control flow like branches or an direct error return.
Anyway, the question was how to use macros with assembly, I showed one way, using inline functions is another one.
A third one actually is to write the function with the assembler and not embedded in C with the inline assembler.
The assembler has its own macro's which work different from the C language ones as they do not just replace text but instead they are inserting instructions. Assembly macros also support conditional compilation internally, so for different arguments they can generate completely different output.

Daniel
0 Kudos

1,105 Views
Deadstar
Contributor I
Hey guys,

I got a bit lost looking at your posts. Perhaps if I explain more clearly I will make more sense.

I am looking to replicate the following code 20X

Code:
LDAA 0,XSTAA PTT      LSL PTTLSL PTTLSL PTTLSL PTTLSL PTTLSL PTTLSL PTTINX

 Now every clock cycles is very important, I really need to minimize them, so instead of just using copy/paste 20x I was hoping I could use some sort of a macro to make it easier to read.

The assembler above is embedded within C code, hence I used __asm{} around it.

Thanks again, I appreciate the effort,

Colin

0 Kudos

1,105 Views
bigmac
Specialist III
Hello Colin,
 
You appear to be shifting a single bit from LSB to MSB position.  Firstly, there is a simpler and faster way to do this.  By rotating in the opposite direction, and using the accumulator for the rotate, you will save many cycles.
 
   LDAA  0,X
   RORA
   RORA
   ANDA  #$80
   STAA  PTT
   INX
      
A macro might take the following form -
 
Code:
#pragma NO_STRING_CONSTR#define shift_PTT  __asm ldaa 0,x; __asm rora; __asm rora; asm anda #$80; __asm staa PTT; __asm inx;

 Not a pretty sight!
 
Regards,
Mac
 


Message Edited by bigmac on 2008-03-07 12:13 PM
0 Kudos

1,105 Views
Deadstar
Contributor I
The reason I used all the shifts is I am looking to output all the bits in PTT in order as quickly as possible - i.e. looking at PTT-bit7.

Why do you use __asm for every line? Could I not just enclose all the assembler in one __asm{} as below?

Code:
#pragma NO_STRING_CONSTR#define shift_PTT  __asm{LDAA 0,XSTAA PTT  LSL PTTLSL PTTLSL PTTLSL PTTLSL PTTLSL PTTLSL PTTINX };

 Also if I use this method would it add any additional clock cycels, or does the compiler litterally replace all shift_PTTs by this code?

Colin

0 Kudos

1,105 Views
CompilerGuru
NXP Employee
NXP Employee
Using the block syntax for __asm {} does not work as with this syntax instructions are line terminated, and that the output of  a single C macro is a single line. Check the compiler manuals high level inline assembly about this too. (this was btw the first trap I mentioned in the prev post)
And C's macro replacement is a simple text replacement utility, therefore it will generate the identical output as search and replace with a text editor.
I guess in your code snippet, you lost some line continuations ('\') at the line ends in the macro.

Daniel
0 Kudos