Tags
assembly, AT&T syntax, GAS syntax, local label, macros, technical, x86_64
Recently while coding up some assembly files, I came across a problem : I needed to create a loop in my macro. This involved including a label inside macros definition.
Before you read any further, please make sure that your .asm file is in GAS or AT&T syntax. Intel / TASM / MASM compilers and syntax have a different ways to define local labels 🙂 Using regular label definition syntax used in regular .asm files led to compile time errors. If macro_foo was used just once, all was good. But like a useful macro, if macro_foo was used multiple times, it gave multiple definitions error.
#define macro_foo \
movb $0x5, %al \
label_foo:\
cmp $0x4, %al \
/* If %al > $0x4, go to label_foo.*/ \
jg label_foo \
#endif
Error: symbol `label_foo’ is already defined What happened was each time macro_foo was expanded, the label label_foo was expanded as it is – leading to multiple definitions throughout the module for each usage of foo_macro. To overcome the multiple definitions problem, a local label is needed.
GAS syntax defines a local label as any positive integer. Note : x –> any positive integer. However if x = {0, 1, 2, 3 …., 9} – the first 10 local labels, it is implemented more efficiently.
#define macro_foo \
movb $0x5, %al \
4:\
cmp $0x4, %al \
/* If %al > $0x4, go to label 1’s most recent definition.*/\
jg 4b \
#endif
Now to refer to the latest definition, which in most cases you will be using, suffix ‘b’ to the label. The ‘b’ indicates backwards referencing. To forward reference it (honestly haven’t figured out a use case for that), suffix ‘f’ to the label.