[avrasm2] weird? macro expansion problem

Go To Last Post
20 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, I have a weird problem (bug?) with macro expansion while compiling with avrasm2.exe. I'm not sure whether I'm just doing something wrong, or it is working as intended, or it's a bug.

Problem: if there is a number in symbol name, before the macro parameter reference, compilation ends with an error.

 

Example:

.equ    foo1bar2    =0
.macro  testmacro
    ldi r16,foo1@0
.endmacro
    testmacro bar2

compilation ends with error: bar2: Unknown instruction or macro.

.equ    foo1bar2    =0
.macro  testmacro
    ldi r16,foo1bar@0
.endmacro
    testmacro 2

compilation ends with error: syntax error, unexpected INTEGER.

.equ    foo1bar2    =0
.macro  testmacro
    ldi r16,exp2(foo1@0)
.endmacro
    testmacro bar2

compilation ends with error: syntax error, unexpected SYMBOL.

 

Everything works just fine if there is macro parameter reference before the number:

.equ    foo1bar2    =0
.macro  testmacro
    ldi r16,f@1o1@0
.endmacro
    testmacro bar2,o

Assembly complete, 0 errors. 0 warnings

 

Same thing occurs if you try it with labels instead of symbols.

Any help will be appreciated.

Sorry about lack of code segments, code editor just didn't want to start, may edit it later if I find out how.

Edit: fixed code segments, it worked while editing.

This topic has a solution.
Last Edited: Fri. Jul 28, 2017 - 04:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you want to try string concatenation wouldn't you be better using the preprocessor support and the ## operator?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

If you want to try string concatenation wouldn't you be better using the preprocessor support and the ## operator?

 

Preprocessor macro concatenation produces the same error if used within normal (directive?) macro.

 

We also don't use preprocessor macros. Don't ask me why, they just aren't in any of our software. I probably could start using them, but they wouldn't really help in this case (I think).

 

This one macro uses various variables (.db) and constants (.equ) with various names and is called X times. The only thing these names have in common is the part that needs to change between uses. Most of them don't have any numbers before the parameter, so using directive macro I would need 5 parameters (1 for most variables, 4 for a specific few). If I remade the macro to preprocessor macro, I would need parameter for every variable.

I may be wrong about this, haven't used the preprocessor macros that much.

 

Edit: my bad, preprocessor macros could be used, but would make the code look ugly.

Last Edited: Wed. Jul 26, 2017 - 05:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is a bug in the assembler. It has been assigned the ID  AVRASM-183  for future reference.

 

Using assembler macros for string concatenation is a bit outside the anticipated use cases, but there is no particular reason it shouldn't work (or at least behave consistently).

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@rkruse

 

Does that apply to ## in the pre-pro too? Otherwise it'd presumably be a temporary workaround. (or does that prepro even do ## ?)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
(or does that prepro even do ## ?)

Concatenation (##)

The concatenation operator concatenates two preprocessor tokens, forming a new token. It is most useful when at least one of the tokens are a parameter to a function-type macro.

Example

#define FOOBAR subi

  1. #define IMMED(X) X##i
  2. #define SUBI(X,Y) X ## Y

When the IMMED and SUBI macros are called like this:

  1. IMMED(ld) r16,1
  2. SUBI(FOO,BAR) r16,1

they will be expanded to

  1. ldi r16,0x1
  2. subi r16,0x1
  3. ...

For the OP:  If you need to do "stuff", then I'd suggest embracing this millennium and use the ASM2 facilities.  ASM1 was/is pretty primitive except for "straingt-line" work. 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
For the OP:  If you need to do "stuff", then I'd suggest embracing this millennium and use the ASM2 facilities.  ASM1 was/is pretty primitive except for "straingt-line" work. 

 

This is a legacy application that still needs to be supported.

I kinda lost you on ASM2 and ASM1, what did you mean by that? The only thing I found would be the usage of avrasm2.exe instead of avrasm.exe (which I already am doing) and using the added features. The workaround would be using preprocessor macros, but as I mentioned in the post earlier, I don't think that would help in this particular case.

 

Edit: Well it would be possible to use preprocessor macros, but single line comments would be obnoxious to do and whole macro would look ... different? with all those C style comments all over the place. Also, is it possible to have preprocessor macro expansion in the list file?

Last Edited: Wed. Jul 26, 2017 - 05:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, it shouldn't. Preprocessor string concatenation is a documented feature that we have test cases for, while using traditional assembler macros for this purpose is something we never thought of and therefore not tested.

 

I will take a look at this bug today and see if it can be fixed with reasonable effort.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Slaynie wrote:
Edit: Well it would be possible to use preprocessor macros, but single line comments would be obnoxious to do and whole macro would look ... different? with all those C style comments all over the place.

???

 

What does using pre-processor facilities introduced in ASM2 have to do with comments?!?

 

In my quick take:

-- You are using ASM2

-- Why not use the facilities it gives you to do what you want, instead of fighting with your primitive approach?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Slaynie wrote:
Also, is it possible to have preprocessor macro expansion in the list file?

LISTMAC

Turn macro expansion on.

The LISTMAC directive tells the Assembler that when a macro is called, the expansion of the macro is to be shown on the listfile generated by the Assembler. The default is that only the macro-call with parameters is shown in the listfile.

Syntax

.LISTMAC

Example ...

I guess I might suggest a review of the assembler "manual".

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I found the issue causing this bug, the next assembler version (2.2.7) will have this fixed. I can not tell when that version will become available, I think there is no separate download for the assembler, it comes as part of the Atmel Studio distribution.

 

Regarding the question about AVRASM2 vs AVRASM1: AVRASM(1) (version 1.x) was the original  AVR assembler (executable named avrasm32), AVRASM2 is a total re-write released about 2005. AVRASM1 was deprecated and received no updates or new device support after AVRASM2 was officially released, but was distributed in parallel during the lifetime of AVR Studio 4. Starting with AVR Studio 5 (if memory serves) only AVRASM2 has been distributed.

 

FYI, the test case for this will look something like this:

 

        ;; Tests for bug AVRASM-183. Valid from v 2.2.7
        .equ    foobar    = 3
        .macro  testmacro
        ldi r16,foo@0
        .endmacro
        testmacro bar

        .equ    foo1bar2    =0
        .macro  testmacro2
        ldi r16,foo1@0
        .endmacro
        testmacro2 bar2

        .equ foo1 = 0xaa
        .macro xxx
        ldi r@0, @1
        .endmacro
        xxx 16,  foo1

        .equ foo2 = 0xbb
        .macro xxx2
        ldi r1@0, @1
        .endmacro
        xxx2 6,  foo2

        .macro xxx3
        ldi r@0, @1@2@3 + 5
        .endmacro
        xxx3 16, 1, 2, 3
 
        .macro xxx4
        ldi r@0, @1_4
        .endmacro
        xxx4 16, 0xa

#ifdef failing
        .macro xxx5
        ldi r@0, 1@2
        .endmacro
        xxx5 16, 23
#endif        

The last example (inside #ifdef failing) will not work. The concatenee cannot start with a digit, fixing this would involve deep changes in the parser which is too risky for little gain. Also notice the undescore trick in the previous example (macro xxx4). I leave it as an exercise for the reader to figure out why the undescore is required. :-)
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think there is no separate download for the assembler,

But it's only a single file, you could accidentally drop a copy under the table, no one is going to tell on you..... angel

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:
no one is going to tell on you.....
John, shame on you..

@rkruse (just change the name so only those "in the know" will get it!)devil

David

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
What does using pre-processor facilities introduced in ASM2 have to do with comments?!?

 

Line comments will break macro (well at least I don't know how they would work), need to use block comments. That would mean changing every single line of the function instead of changing a few substrings (/* */ or \\ at every single line).

 

theusch wrote:
Why not use the facilities it gives you to do what you want, instead of fighting with your primitive approach?
 

 

I'm keeping the coding style the same. I don't know why we don't use preprocessor macros, may be because of the list file, may be for legacy reasons. I'm not writing a new application, I'm fixing an old one where there are a few functions that are almost carbon copy of each other, the only difference is 1 number in all used labels / symbols. The fastest way is transforming one of them into a .macro and calling them separately. Transforming them to a #define would take more effort, would break the unwritten coding style and make the list file harder to read.

 

theusch wrote:
LISTMAC Turn macro expansion on. The LISTMAC directive tells the Assembler that when a macro is called, the expansion of the macro is to be shown on the listfile generated by the Assembler. The default is that only the macro-call with parameters is shown in the listfile. Syntax .LISTMAC Example ... I guess I might suggest a review of the assembler "manual".

 

That doesn't expand preprocessor macros, only directives. Guess you shouldn't rely only on the manual, eh? (So I say just waiting to be proven wrong for missing some obscure reference in manual for preprocessor macros).

 

rkruse wrote:
I found the issue causing this bug, the next assembler version (2.2.7) will have this fixed.

 

Thanks!

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, for anyone wanting to try it, please find it attached.

 

It has passed all regression tests, but has not seen much use yet, so use at own risk. Please let me know if it breaks something.

 

Unzip the file and drop avrasm2.exe at the correct place in the Atmel Studio installation (I dont remember where that is anymore). If you are faint of heart you can rename the existing avrasm2.exe first.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Slaynie wrote:
Line comments will break macro (well at least I don't know how they would work), need to use block comments.

I'm still lost.  If you are using ; comments, why can't you continue to use them?

 

Indeed, though, if you are going to use C-style macro facilities, soem kind of #define line for example, then I'd expect the pre-processor to act pretty much like C w.r.t. multi-line macros.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You could use the C pre-processor (-E) to get an expansion of the macros separate from assembly.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

rkruse wrote:

OK, for anyone wanting to try it, please find it attached.

 

It has passed all regression tests, but has not seen much use yet, so use at own risk. Please let me know if it breaks something.

 

Unzip the file and drop avrasm2.exe at the correct place in the Atmel Studio installation (I dont remember where that is anymore). If you are faint of heart you can rename the existing avrasm2.exe first.

 

Thanks, looks like it works (macro expansion works correctly, produced .hex and .eep files are identical). Patiently waiting for "official" release!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Slaynie wrote:

 

Thanks, looks like it works (macro expansion works correctly, produced .hex and .eep files are identical). Patiently waiting for "official" release!

 

Good. You will need some patience though, I think next studio release is planned this autumn sometimes. The file I posted is however an "official" build, in the sense that if nothing more needs to be done to the assembler before release, the very same file will go into the Studio installer build machinery  when the time is ripe.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

Slaynie wrote:
Line comments will break macro (well at least I don't know how they would work), need to use block comments.

I'm still lost.  If you are using ; comments, why can't you continue to use them?

 

Indeed, though, if you are going to use C-style macro facilities, soem kind of #define line for example, then I'd expect the pre-processor to act pretty much like C w.r.t. multi-line macros.

This is off-topic related to this thread's topic but let me try to clarify:

 

There are some issues using a C style preprocessor in an assembler setting, particularly because of different comment syntax (';' has a totally different meaning in C and the assembler).

 

If you need to have comments inside a preprocessor macro (#define), you must use block-style C comment (/* ... */). Preprocessor macros are conceptually one line, so the other forms of comments will effectilvely comment out the rest of the macro (even if it spans over multiple lines). Proprocessor macros are best suited for defining constents and doing various string manipulations and the like.

 

You should use assembler macros (.macro) for anything containing assembler code. Particularly if the macro contains labels: Assembler macros guarantee that labels are unique for each invocation of the macro (separate namespaces), the preprocessor does no such thing, it knows nothing about assembler syntax.

 

Be aware that macros defined with the preprocessor (#define) and symbols defined with assembler directives (.equ and the like) are different entities. When using conditionals, #if/#ifdef only sees preprocessor symbols (defined with #define), while .if/.ifdef only sees assembler symbols (defined with .equ and the like).

 

Finally: Don't use preprocessor conditionals (#if/#ifdef) inside an assembler macro.