avr-gcc inline assembler labels

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

I just have learned something about the inline assembler's labels: I am using routinely L1%=, L2%= etc. and have no problems so far (sort of boring, maybe, but those assembler snippets tend to be short and relatively similar to each other, so I saw no need to be more inventive in the names).

Now, in two different routines I used L11%= in one, and L1%= in the other.

It happened, that %= got replaced by a unique number for each asm statement, as the documentation says - particularly, by 39 in the first, and by 139 in the other. It means, that I ended up with two L1139 labels... which of course results in assembler error.

Somebody more competent than me might perhaps add this small snippet of information to the Cookbook/avr-libc documentation, for the benefit of the future generations...

Jan Waclawek

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

Personally I would avoid inline assembler like the plague, and write the necessary code in pure assembler files.

Normally you would mangle non-entry labels by appending a number string to the base entry label. In your case you are choosing "L", "L1", "L2" ... as the base entry labels. A similar recipe for disaster with ANY assembler.

If they are snippets, why not use Unix-style local labels? (which I do not like)

David.

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

Is there some reason not to use local labels in gas to avoid name pollution? The price you pay is the need for the 'f's and 'b's:

http://sourceware.org/binutils/d...

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

As I was asm-programming on maybe half a dozen of different platforms, and still actively use '51 asm - not to mention non-gcc/gas AVR asm - I try to avoid using "specialties" as such.

There are easy remedies for the problem - one mentioned by David above, using a "hand-unique" "base" label for each routine; other is to use a non-digit character as the last one before the %= (meantime, I simply replaced all %= by _%= ).

JW

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

david.prentice wrote:
Personally I would avoid inline assembler like the plague, and write the necessary code in pure assembler files.

And the reason is?

(Some of those snippets are inlined because of speed - that's mostly the reason for using asm in C anyway, isn't it - so I would not like to lose cycles (and stacks) and on the calls. But I do learn ;-) ).

david.prentice wrote:
Normally you would mangle non-entry labels by appending a number string to the base entry label. In your case you are choosing "L", "L1", "L2" ... as the base entry labels. A similar recipe for disaster with ANY assembler.

Well... I think I got to the wrong track by trusting too much to "%= will be replaced by unique identifier"... ;-)

david.prentice wrote:
If they are snippets, why not use Unix-style local labels? (which I do not like)

See above.

Jan

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

The simplest way to avoid the problem
is to avoid following a digit with %= .
In inline assembly, I usually use local labels.

Iluvatar is the better part of Valar.

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

skeeve wrote:
The simplest way to avoid the problem
is to avoid following a digit with %= .

Exactly.
I would expect the Cookbook would say this.
"Don't put a digit before the %=."

JW

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

wek wrote:
david.prentice wrote:
Personally I would avoid inline assembler like the plague, and write the necessary code in pure assembler files.

And the reason is?

The syntax is really horrible.

Obviously there may be occasions for snippets inside a large C function. In which case you have no choice but "inline".

Small C functions can be generated into an ASM file by: gcc -S file.c
This creates readable code that you can hand-optimise. Since you use several assemblers, I suspect that you would be happier with a conventional syntax. I certainly am.

If your code is to run on several platforms, this approach is a lot easier to maintain.

David.

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

David,

Yes, the syntax is really horrible... :-O

On the other hand, I guess, to use "real" asm, that's a bunch of another hows and whys. For now, I am happy with that horrible one. Most of the time what I do is copy/paste/slightly modify what my colleague already started anyway - that is why I used the same labels everywhere...

But I am trying to learn. Given a substantial task in asm, I will look into the "real one".

Thanks for the guidance again.

Jan

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

david.prentice wrote:
wek wrote:
david.prentice wrote:
Personally I would avoid inline assembler like the plague, and write the necessary code in pure assembler files.

And the reason is?

The syntax is really horrible.

I'm not aware of a better one, but then, I'm only aware of two.
Does someone know of a better inline assembly syntax?

Iluvatar is the better part of Valar.

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

Yes, GCC's inline assembly syntax is complex and difficult to learn. But as with engineering, there are trade-offs. GCC's inline assembly is incredibly powerful, especially in how it can interface to the outside C world. I know of no other compiler that offers such capability and features with their inline assembly syntax. Most other compilers have very simple inline assembly syntax. They trade off for that simplicity, by reducing the complexity and eventually its overall capabilities, which makes it difficult to use for complex needs.

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

EW wrote:
Yes, GCC's inline assembly syntax is complex and difficult to learn.

Oh, its the semantics, and the "interrelated" stuff, which is complex, but it's okay. Writing standalone asm functions linkable properly to C certainly isn't much simpler.

But it's the "grammar" we (or at least I) don't like.

If you are used to write asm - and you write a lot - then you know that to write even a simple function takes to write a lot of lines. Now, if you are compelled to put each statement into quotes and add /n (and /t for style), you quickly learn to hate it.

Besides, editors have hard time highlighting it - it's just a string for them.

Said this, I 100% agree with all you've written above.

JW

PS. That I personally don't like the AVRs per se, nor their asm mnemonics, is a completely different topic... ;-)

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

Jan,

Eric has put it very well. The horrible syntax is very powerful for the purpose intended.

Following the "gcc -S" route is very straightforward. You can tweak snippets of this code, and always have the underlying C source for testing and compatibility. Most importantly, the C preamble and return sequences are already done for you.

I too have preferences for certain manufacturer's mnemonics and syntax. But you just have to live with the platform and target that you have chosen.

David.

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

david.prentice wrote:
Eric has put it very well. The horrible syntax is very powerful for the purpose intended.

Oh, I don't think the quotes and the \n are a necessity. Getting rid of them would substantially increase the readabiliy/writebility of the inline asm, while not sacrificing any of its powers. However, I see that it would be paramount task to rewrite all the framework needed to get rid of it, especially with backwards compatibility in mind.

Mind, I don't complain about the rest (the input/output, automatic "unique" labels extension etc.); contrary, I acknowledge the capabilities it provides. I would welcome a more thorough documentation, though, even at some appropriate cost (a decent book, say).

david.prentice wrote:
Following the "gcc -S" route is very straightforward. You can tweak snippets of this code, and always have the underlying C source for testing and compatibility. Most importantly, the C preamble and return sequences are already done for you.

David, you certaily know that I still would feel uncomfortable if I would not know the reason and purpose and effect of all the items in such "generated source", should I modify it.

david.prentice wrote:
I too have preferences for certain manufacturer's mnemonics and syntax. But you just have to live with the platform and target that you have chosen.

Oh, after what I've said these days here - and keep saying on other fora all the time - do you really think it was *I* who has chosen this platform and target? ;-)

(Although, to be honest, I most probably would at least think about it, would I be in the situation the guys for whom I am working now were at the time they decided for the AVRs - they actually did abandon an older line of products based on the T89C51RD2 because of troubles with availability when Atmel took over Temic...)

Jan

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

Quote:

David, you certaily know that I still would feel uncomfortable if I would not know the reason and purpose and effect of all the items in such "generated source", should I modify it.

Most compilers publish their calling conventions and register use. It is your responsibility to comply with them in any inline code or linked ASM module. You do exactly the same with sdcc or Keil.

You can always take the "ISR" approach to transparency. i.e. preserve everything before your code and restore afterwards. Not efficient but you can have a complete disregard of compliance with any compiler.

As a silly question. Why not go from Temic/Atmel to Philips/NXP ? IMHO if your application must use external memory you could use any family. However if you can find a family that has sufficient resources on-chip, life is a lot simpler.

David.

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

david.prentice wrote:
Quote:

David, you certaily know that I still would feel uncomfortable if I would not know the reason and purpose and effect of all the items in such "generated source", should I modify it.

Most compilers publish their calling conventions and register use. It is your responsibility to comply with them in any inline code or linked ASM module. You do exactly the same with sdcc or Keil.

Yes, and there's more: linker-related issues like memory allocation, paging conventions with the big Megas (yes, I am approaching those dark muddy waters, too... :-| ), project integration... I don't say it's all hard, it's just another bunch of things to learn, and I just chose the easy way for now. I might have to revisit it later...

david.prentice wrote:
You can always take the "ISR" approach to transparency. i.e. preserve everything before your code and restore afterwards. Not efficient but you can have a complete disregard of compliance with any compiler.
Yes and no. It kills some/much of the edge resulting from using asm, so it's questionable whether it's worth at all. Also, I don't really like to clobber up the stack - about which I am already uneasy (is there any tool for stack analysis?)

david.prentice wrote:
As a silly question. Why not go from Temic/Atmel to Philips/NXP ? IMHO if your application must use external memory you could use any family. However if you can find a family that has sufficient resources on-chip, life is a lot simpler.

This is a long story and quite OT here, we can discuss it privately if you want. One of the major reasons was, that NXP's '51 line is completely unknown here. In fact, most of the people here still think '51=AT89C5x, despite my years-long tireless preaching in the local "media".

Jan

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

Quote:

On the other hand, I guess, to use "real" asm, that's a bunch of another hows and whys.

Err, why?

It's the same assembler and it's possibly easier to make use of its directives in a standalone .S than trying to embed them inline. The only tricky bit is conforming to the ABI but it's hardly complicated as it's expressed in less than 20 lines here:

http://www.gnu.org/savannah-chec...

with an example here:

http://www.gnu.org/savannah-chec...

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

clawson wrote:
[...]it's hardly complicated as it's expressed in less than 20 lines

Oh, Maxwell said it all about electromagnetic phenomena in 4 equations... ;-)

The hard thing on teaching is to try to recollect how did it feel like when you did not have all the knowledge you have.

JW

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

wek wrote:
Oh, its the semantics, and the "interrelated" stuff, which is complex, but it's okay. Writing standalone asm functions linkable properly to C certainly isn't much simpler.

But it's the "grammar" we (or at least I) don't like.

If you are used to write asm - and you write a lot - then you know that to write even a simple function takes to write a lot of lines. Now, if you are compelled to put each statement into quotes and add /n (and /t for style), you quickly learn to hate it.

Is the grammar horrible or just easy to dislike?

To Keil and IAR inline assembly (ex-)users:
How much inline assembly do you write?
How?
My recollection is that whenever I used a register in IAR inline assembly,
I had to check the compiler output to make sure I'd guessed the right register.

Iluvatar is the better part of Valar.

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

skeeve wrote:
Is the grammar horrible or just easy to dislike?

Well, like pain in the ***. One could stand it for a while, but not for too long... ;-)

skeeve wrote:
To Keil and IAR inline assembly (ex-)users:
How much inline assembly do you write?
How?
My recollection is that whenever I used a register in IAR inline assembly,
I had to check the compiler output to make sure I'd guessed the right register.

As far as I know, mixing asm to C in Keil results even in losing the ability to optimise...

I appreciate the possibilities offered by gcc's inline, and, as said above, it is truly powerful. But it's like the nitroglycerine - powerful and hard to handle. I'd like some dynamite better.

JW

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

wek wrote:
skeeve wrote:
]To Keil and IAR inline assembly (ex-)users:
How much inline assembly do you write?
How?
My recollection is that whenever I used a register in IAR inline assembly,
I had to check the compiler output to make sure I'd guessed the right register.

As far as I know, mixing asm to C in Keil results even in losing the ability to optimise...

I appreciate the possibilities offered by gcc's inline, and, as said above, it is truly powerful. But it's like the nitroglycerine - powerful and hard to handle. I'd like some dynamite better.

It seems to me that gcc's inline assembly's operands
are the difference between nitroglycerin and dynamite.
They tell the compiler enough about what you
are doing to avoid blowing it up in your face.

Has anyone else used IAR's inline assembly?

Iluvatar is the better part of Valar.

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

I did a long while ago. IIRC, it's about like any other compilers' inline assembly; straight forward text insertion.

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

EW wrote:
I did a long while ago. IIRC, it's about like any other compilers' inline assembly; straight forward text insertion.
How can one make that work right?
Were you able to read or write local variables?

Iluvatar is the better part of Valar.