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.
2 Answers 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.
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.
-
The question is about the use of labels in assembly macros, not about the use of variables in C++ functions.Edgar Bonet– Edgar Bonet2023年03月09日 09:13:15 +00:00Commented Mar 9, 2023 at 9:13
Its the aduino uno
... no it's not ... the problem you describe has nothing to do with the type of arduino