From what I understand, NASM (like all good assemblers) allows you to define local labels by prefixing them with a period, and it allows later definitions to override previous ones.
The code I've seen demonstrating this looks like:
part1 mov ax, 10
.loop ; do something
dec ax
jnz .loop
part2 mov ax, 50
.loop ; do something
dec ax
jnz .loop
In this case, the later definition overrides the earlier one so that the correct label is selected.
However, I can't see how this works in the following scenario.
part1 mov ax, 10
.loop jz .fin
; do something else
dec ax
jmp .loop
.fin
part2 mov ax, 50
.loop jz .fin
; do something else
dec ax
jmp .loop
.fin
At the point where jz .fin
in the second loop is assembled, surely the earlier instance of .fin
would still be active and it would jump to the wrong location.
Or is NASM smarter than that and uses some other method to decide which label is active at any given time?
A local label is a number in the range 0-99, optionally followed by a name. Unlike other labels, a local label can be defined many times and the same number can be used for more than one local label in an area. Local labels do not appear in the object file.
Actually, that understanding isn't quite correct. The local labels aren't stand-alone items, they actually associate themselves with the most recent non-local label.
NASM manual section 3.9 Local Labels
So the second code example effectively becomes:
part1 mov ax, 10
part1.loop jz part1.fin
; do something else
dec ax
jmp part1.loop
part1.fin
part2 mov ax, 50
part2.loop jz part2.fin
; do something else
dec ax
jmp part2.loop
part2.fin
and the problem then disappears.
In fact, you can actually refer to the local labels as non-local ones. In other words, if you wanted to leave part1
and totally skip part2
completely, you could just use something like:
jmp part2.fin
from somewhere within part1
. Using .fin
from within part1
wouldn't work since that would select part1.fin
, but the fully qualified part2.fin
would do the trick.
At the point where
jz .fin
in the second loop is assembled, surely the earlier instance of.fin
would still be active and it would jump to the wrong location.Or is NASM smarter than that and uses some other method to decide which label is active at any given time?
Let's find out!
C:\nasm>nasm -f bin -o locals.com locals.asm && ndisasm locals.com
00000000 B80A00 mov ax,0xa ; part1: mov ax, 10
00000003 7403 jz 0x8 ; .loop: jz .fin
00000005 48 dec ax ; dec ax
00000006 EBFB jmp short 0x3 ; jmp .loop
00000008 B83200 mov ax,0x32 ; .fin: part2: mov ax, 50
0000000B 7403 jz 0x10 ; .loop: jz .fin
0000000D 48 dec ax ; dec ax
0000000E EBFB jmp short 0xb ; jmp .loop
; .fin:
So the first jz .fin
jumps to the first instance of .fin
, and the second jz .fin
jumps to the second instance of .fin
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With