Label Duplicates in Assembly

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

Hey there, I was wondering how one would go about labeling parts of their code in assembly in order to deal/avoid duplicate names.

Let's say I have foo() and bar() which both for some reason or another really need the same name for a label. Can this be done?

 

Of course it is possible to give larger and larger names to avoid duplicates, but this seems counterproductive to readability.

 

I saw someone use the .SET directive to set the value of a label to the PC, which is a clever workaround, however the following code wouldn't work as expected:

foo:
    .set loop = pc
    // foo loop that calls bar
    rcall bar
    // some branch code
    rjmp loop
    ret

bar:
    .set loop = pc
    // important loop code
    ret

The loop label never gets reset to what it was when defined initially in foo.


EDIT: there was a misconception where I assumed .set was called at run-time which of course is nonsense! The example code would work just fine.

Last Edited: Fri. Jan 10, 2020 - 11:48 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

.set is the wrong way to change things at run-time (eg, while it is executing). It does NOT do what you think. Also, .set DOES NOT create a label!

 

You need to store PC in registers.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Fri. Jan 10, 2020 - 11:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"The SET directive assigns a value to a label. This label can then be used in later expressions. Unlike the EQU directive, a label assigned to a value by the SET directive can be changed (redefined) later in the program." - AVR directives page.

 

When I test this it seems to set a label, even one never created before, and I can jump to it. Unless I'm understanding it completely wrong isn't that the same as creating a label?

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

I think that does not work dynamically. I think that it only happens once, when it is assembled.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

In the olden days, I would just have labels like:

 

foo:

     ..

     ..

     brne foo_1

foo_1:

     ret

 

bar:

     ...

     ..

     breq bar_1

bar_1:

     ret

 

or you could have something like foo_loop and bar_loop. I don't think we're limited to 8 chars these days.

 

 

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

>Hey there, I was wondering how one would go about labeling parts of their code in assembly in order to deal/avoid duplicate names.

 

I'm not quite sure what you are after, but local labels can be used to limit the need to come up with label names-

 

https://sourceware.org/binutils/docs-2.23.1/as/Symbol-Names.html

(may be better docs out there, this is first I found)

 

foo:

rcall 1f

2:

rcall 2f

rjmp 3f

1:

ret

3:

rcall 1f

rcall 1b

rjmp 2b

2:

ret

1:

ret

 

I think that is an infinite loop, if I did i correctly.

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

In my assembler days I would follow Kartman's scheme in #5

Or create macros with local labels.

 

How big are your source files?

You need to follow some plan.   Keeping track of Assembler symbols is a nightmare.

 

If you compile into individual object files,   the linker will only need to be told about global labels.

 

GCC was designed for HLL compilers.   Housekeeping is easier with C, C++, ...

Productive people write in HLL with the occasional ASM module for efficiency.

Brave people write in ASM-only.

 

David.

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

You can put either function in different modules and then link them together.
.
And why is there a "need" for the same name?

avrfreaks does not support Opera. Profile inactive.

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

local labels can be used

Note that "local labels" are a gnu assembler thing.  I'm pretty sure that the Atmel assemblers don't have them.

 

 

say I have foo() and bar() which both for some reason or another really need the same name for a label.

You probably REALLY don't need to have the same names.
Historically, assembler programmers generate unique labels manually.  Sometimes there are hacks that can be used within macros.
https://github.com/WestfW/struct...


       _do
         call movechar
         cpse r1, r2
       _until skp

(again, though, this is gnu assembler.)

   _do
     call movechar
 cpse r1, r2
   _until skp
   _do
     call movechar
 cpse r1, r2
   _until skp
   _do
     call movechar
 cpse r1, r2
   _until skp
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As David says, if your assembler code is getting so big and complex that this is a real issue, then you should really be  using a High-Level Language (HLL).

 

The whole point of a HLL is that it massages all this mundane, laborious, arcane detail for you - in this case, with things like block scope.

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm writing assembly for my Atmega328p from scratch, making libraries for working with different datatypes and such. The amount of code is getting larger and larger, so I want to use a method to keep simple labels such as 'loop' available for any future code.

The simplest solution so far I've read here is the one I've been using; simply naming loops like foo_loop and bar_loop.

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

But such names are of no help because they give zero insight. "loop" basically means "jumping backwards conditionally". Give names that tell what the loop is doing or is good for.

avrfreaks does not support Opera. Profile inactive.

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

JDArduino wrote:
The amount of code is getting larger and larger

You're not just lumping everything into one huge source file, are you?

As  SprinterSB said, you need to be using separate files to modularise your code.

Again, if it's getting that big & complex, you really should be using a HLL ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

awneil wrote:
Again, if it's getting that big & complex, you really should be using a HLL ...

 

I knew it wast time to change to an HLL when I had created so many assembly macros that they were starting to become an HLL themselves...

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

awneil wrote:
You're not just lumping everything into one huge source file, are you?
But that IS the way the Atmel assembler works. There is no linker. Everything is built in one pass of the assembler. Even if you split it all into separate .asm files you have one master.asm that just .include's all the others so symbols across all, the source has to have unique names (and there's nothing like C++ namespace to help).

 

If you write "libraries" so you have adc.asm, uart.asm etc that you may later join together in some project.asm the best you can do in terms of avoiding name pollution is perhaps to do something like pre fixing every label in adc.asm with adc_ and everything in uart.asm with uart_ etc but this still does not avoid adc_loop problems as you'd still need adc_loop1, adc_loop2 etc

 

But I'd go with what SprinterSB said don't just use generic names like "loop" but give more meaningful names like adc_wait_for_conversion or whatever.

Last Edited: Sun. Jan 12, 2020 - 02:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, I'm putting my functions in files like "uint16_t" and "sfloat32_t" and then just include them in the main file of whatever program needs them.

And using a higher level language would be counterproductive as I'm doing this in assembly for fun as a challenge.

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

 how one would go about labeling parts of their code in assembly in order to deal/avoid duplicate names.

The compiler will generate an error on the duplicate name ...simply click on the error & rename to something else...search (ctrl-f) for any references to the duplicated (only)name & update to the new name.

Repeat until all errors are cleared. 

--------------------------------------------

I remembered seeing something at least 8 years ago talking about the issue...can't believe I was able to find it in 1 minute...I was very interested in it at the time:

http://ww1.microchip.com/downloads/en/DeviceDoc/avr_builder.pdf

 

https://scienceprog.com/algorithm-builder-for-avr-if-you-like-assembling/

This is not a classical like text editor, but GUI enables enter programs as flow charts and tree like structures.

Such visual type of program developing is convenient tool because you don’t have to remember tons of labels, reduces error probability

and such logical visualisation reduces development time.

 

After a big dig (using my internet shovel), I found a place where you can download & try it out (just for fun):

http://rfanat.ru/s19/Algorithm_Builder.html

 

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Mon. Jan 13, 2020 - 12:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

But that IS the way the Atmel assembler works. There is no linker. Everything is built in one pass of the assembler. Even if you split it all into separate .asm files you have one master.asm that just .include's all the others so symbols across all, the source has to have unique names (and there's nothing like C++ namespace to help).

 

If you write "libraries" so you have adc.asm, uart.asm etc that you may later join together in some project.asm the best you can do in terms of avoiding name pollution is perhaps to do something like pre fixing every label in adc.asm with adc_ and everything in uart.asm with uart_ etc but this still does not avoid adc_loop problems as you'd still need adc_loop1, adc_loop2 etc

 

But I'd go with what SprinterSB said don't just use generic names like "loop" but give more meaningful names like adc_wait_for_conversion or whatever.

 

It also doesn't accept the '1f' syntax mentioned in #6.

 

But since I write a lot of AVR assembler code, thought I should chime in.  You're right about the prefix - but that's just part of the 'meaningful name' as well.  In an effort to keep things straight, I write out labels in BLOCK_CAPS, and then loop targets inside a given function get the BLOCK_CAPS label suffixed with a lower-case letter, incremented as one goes through the function.  Note also indentation (although this isn't python - I can be a hair inconsistent myself!!).

 

For example, a routine that dumps a 10-character long string array found in the flash memory out to the RS-232 port, might look like this:

 

SER_10CHAR_DUMP:    ; Presumes the location of the string is already in Zptr.
    ldi LoopC0, 10  ; Loop counter

    SER_10CHAR_DUMPa:
        lpm Txbyte, Z+      ; Txbyte is used in SER_CHAR_PUT
        rcall SER_CHAR_PUT  ; which drives the RS-232 registers
    dec LoopC0              ; if zero, dec sets the Zero flag
    brne SER_10CHAR_DUMPa   ; if not zero, loop back for the next one
ret

 

(NB:  I just scribbled that one into the code window.  I have never used that code anywhere) 

 

If the SER_10CHAR_DUMP routine needed another loop (say, there's another string you want) the next loop would be SER_10CHAR_DUMPb:  This, of course, can end up in silliness like FUNCTIONacb: as a loop target inside a heavily edited (constantly inserting more loops) function, but I try to avoid that as best I can (if you need more than 26 targets inside one function, simplify thy function).  Note also that another handy loop target can be FUNCTIONz: which I use as a 'branch here to get out' target (whether the getting out is a 'ret' or an 'rjmp').  S.

 

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

 There is no linker.

I remember being quite surprised by that (and initially a bit befuddled, wondering why I couldn't find the linker info).  Even our embedded 8096  30+ years ago had a linker.

I suppose it is one less source of potential pitfalls (no wrong setup possible!). 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Mon. Jan 13, 2020 - 01:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JDArduino wrote:
No, I'm putting my functions in files like "uint16_t" and "sfloat32_t" and then just include them in the main file

You understand how that "including" works?

 

As clawson said, that is exactly the same as just writing everything in one big file!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

awneil wrote:

You're not just lumping everything into one huge source file, are you?

But that IS the way the Atmel assembler works.

That was kind of hiding behind the question!

 

AIUI, the GCC assembler does support "modular" programming ?

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...