Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NASM local label differentiation

Tags:

nasm

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?

like image 517
paxdiablo Avatar asked Jul 30 '15 03:07

paxdiablo


People also ask

What is local label?

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.


2 Answers

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.

like image 116
paxdiablo Avatar answered Sep 24 '22 13:09

paxdiablo


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.

like image 23
Michael Avatar answered Sep 22 '22 13:09

Michael