IAR: 68HC12: how to __ASM()... not!

Oct 03, 2003 5 Replies

Inlining assembler in a *.c file:-



Both __asm("nop \n")



and



__asm("nop")



work I have abandonned using __asm() it because it only seems to accept a literal string. Trying to pass it an as the manual suggests fails with a syntax error. Also as a last resort I tried this:- __asm ("ldaa SC1SR1") __asm ("std SC1DRH") but it failed with a "unknown variable or function identifier". Despite the proceeding:- #include That contains SC1SR1 etc. It only works if you avoid labels entirely e.g. __asm ("ldaa 0xCC") __asm ("std 0xCD") Urgghh... What I have opted for is to add a *.s33 file to the project containing the assembler [and the macro I originally intended to pass]:- //****************.s33 file ********************* $equates.equ RSEG RCODE //Root-Code: assemble in common or shared rom public init_sci_and_send_a_percent



... init_sci_and_send_a_percent ldaa SC1SR1 //step 1 of clear pending data interrupts std SC1DRH //step 2 of clear pending data interrupts aux_tx '%' //send an % char from RS232 rtc END //****************end of *.s33 file***************


And then calling if from the *.c file //****************.c file ************************ extern init_sci_and_send_a_percent ... init_sci_and_send_a_percent(); //**************end of *.c file******************* It is easy to mix and match *.s33 and *.c files but only the crudest inlining is possible and only by breaking the one definition rule. At the very least we should be able to inline a macro that's the whole point! Robin


Inlining assembler macros usually only works in systemsin which you have a full macro-assembler and you have a C (or whatever) compiler that always convert the HLL to the assembler langauage and the macro assembler is then always run to convert it to binary (or relocatable object) code.

However, many C-compiler that directly produce the binary have a very rudimentary assembler built in to handle those in-line code lines. This assembler does not usually handle any macro expansions or even contain a symbol table.

When you need the same data definitions both in the separately compiled C and (macro)assembly files (assuming the assembler supports some form of "include" statements) is to include a special definition file into both into the C-compilation and into the macro-assembly.

In the common definition file, you can invent some syntax to declare things e.g.

DECLARE A 5

In the C-program before invoking (inluding) this file you can define a macro so that this definition expands to

#define a 5

on the macro assembler side, before invoking the common definition file you can define a macro, which causes the definition above to be recognised as

set a=5

or whatever the syntax for that particular assembler might be.

Paul

This is new to me, thanks very much.

Robin

[...]

Assuming the parameter to __asm is indeed a C string literal, and SC1SR1 is defined as 0xCC (or some other expression the assembler will recognize), something like the following should work:

#define mStringize(p) #p #define mEval_String(p) mStringize(p) #define mInsert_Asm(i,p) __asm(#i " " mEval_String(p))

The intermediate macro (mEval_String) will expand the #define so that mStringize will produce a string of the value of the symbol rather than the symbol itself

For example, if SC1SR1 is #defined as 0xCC, and SC1DRH is #defined as

0xCD, the following code

mInsert_Asm(LDAA, SC1SR1) mInsert_Asm(STD, SC1DRH)

Is expanded (gcc -E) as

__asm("LDAA" " " "0xCC" ) __asm("STD" " " "0xCD" )

Since consecutive string literals separated only by whitespace are concatenated by the compiler, this is equivalent to

__asm("LDAA 0xCC") __asm("STD 0xCD")

Perhaps a variant of this will solve your problem?

Regards,

-=Dave

Change is inevitable, progress is not.

This is very interesting, and it works! Thanks very much. I had no idea that a conversion like this existed. What does "(gcc -E)" mean?

Robin

[...]

Glad to help.

"All problems in Computer Science can be solved by an additional level of indirection." ;-)

I was only trying to say how I had tested it, in case it didn't work with your compiler. Gcc is, of course, the GNU C compiler. When invoked with the -E option, it will simply spit the preprocessed code to stdout so you can see the results of your tricky little macros. The session I used to test the code I posted went something like the following:

--- Begin included file --- C:\Dave>type ppasm.c #define SC1SR1 0xCC #define SC1DRH 0xCD

#define mStringize(p) #p #define mEval_String(p) mStringize(p) #define mInsert_Asm(i,p) __asm(#i " " mEval_String(p))

mInsert_Asm(LDAA, SC1SR1) mInsert_Asm(STD, SC1DRH)

C:\Dave>gcc -E ppasm.c # 1 "ppasm.c"

__asm("LDAA" " " "0xCC" ) __asm("STD" " " "0xCD" )

C:\Dave>

--- End included file ---

The line tells the compiler that the code it is processing (starting with the following line) came from line 1 of the file ppasm.c

Regards,

-=Dave

Change is inevitable, progress is not.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required