0

It's the Arduino Uno. I've spent hours reading on the internet but found nothing yet. If you use a label in the macro, the 2nd time it's called you get a duplicate label error.

3kstc
2212 silver badges13 bronze badges
asked Mar 8, 2023 at 13:45
4
  • 1
    Please provide your code and the exact error message and describe what you are trying to achieve Commented Mar 8, 2023 at 14:32
  • I suggest only using local lables in assembly macros. Commented Mar 8, 2023 at 14:37
  • Its the aduino uno ... no it's not ... the problem you describe has nothing to do with the type of arduino Commented Mar 8, 2023 at 16:53
  • Many thanks Edgar Bonet. Local labels is exactly what I was looking for. Commented Mar 8, 2023 at 22:45

2 Answers 2

2

Just to make the question clearer, let's take a simple example. Consider the following assembly macro that implements a delay loop:

.macro short_delay
 clr r0
repeat:
 dec r0
 brne repeat
.endm

and use it in a program that repeatedly blinks the built-in LED of an Arduino Uno (a faster version of "Blink"):

main:
 sbi DDRB, PB5 ; set pin 13 = PB5 as output
loop:
 sbi PORTB, PB5 ; turn PB5 HIGH
 short_delay
 cbi PORTB, PB5 ; turn PB5 LOW
 short_delay
 rjmp loop

When the assembler expands the macro, it ends up with this:

main:
 sbi DDRB, PB5 ; set PB5 as output
loop:
 sbi PORTB, PB5 ; turn PB5 HIGH
 ; start of short_delay macro
 clr r0
repeat:
 dec r0
 brne repeat
 ; end of short_delay macro
 cbi PORTB, PB5 ; turn PB5 LOW
 ; start of short_delay macro
 clr r0
repeat:
 dec r0
 brne repeat
 ; end of short_delay macro
 rjmp loop

and this fails with

Error: symbol `repeat' is already defined

The solution to this problem is to use, inside the macro, only local labels. These labels are just numbers. When using them, one has to append the suffix "b" (for backwards) or "f" (forwards) depending on whether the label is defined before or after the point where it is being referenced.

The nice thing about local labels is that they are... well... local, and thus they can be safely reused many times. The assembler disambiguates them by choosing the definition that is closer to the point of use, along the specified direction. With a local label (I choose 0), the delay macro becomes:

.macro short_delay
 clr r0
0: dec r0
 brne 0b ; the branch target is the preceding label `0'
.endm

When the macro is expanded, the main program becomes:

main:
 sbi DDRB, PB5 ; set PB5 as output
loop:
 sbi PORTB, PB5 ; turn PB5 HIGH
 clr r0
0: dec r0
 brne 0b
 cbi PORTB, PB5 ; turn PB5 LOW
 clr r0
0: dec r0
 brne 0b
 rjmp loop

Although repeated, the label is not ambiguous, as brne 0b always refers to the closest label 0 along the backwards direction.

answered Mar 9, 2023 at 10:29
-1

Welcome, this is the same thing I had problems a few years back. Define the label in the macro (function) and it will be local and not available to the rest of the world. You can use the same label as many times as you want they just need to be inside a macro.

void macro(int label) 
{ 
 Do something with label and then exit;
} 

You can do whatever you want, say get the value of several pins to see if they are all on then use the return true or false. When you leave the macro all of the variables will be lost and the memory returned to the heap. This is done in several ways in many of the libraries.

sempaiscuba
1,0429 gold badges21 silver badges32 bronze badges
answered Mar 9, 2023 at 3:01
1
  • The question is about the use of labels in assembly macros, not about the use of variables in C++ functions. Commented Mar 9, 2023 at 9:13

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.