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 .finin the second loop is assembled, surely the earlier instance of.finwould 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