Atualizado: 18/10/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Rótulos Locais em Assembly NASM

Em programas Assembly, os rótulos servem para nomear posições específicas no código, facilitando saltos (jmp, je, jne, etc.) e o controle do fluxo de execução. Uma função pode conter vários rótulos, mas cada nome deve ser único dentro do programa.

Se dois rótulos tiverem o mesmo nome, o montador exibirá um erro de redefinição. Veja o exemplo a seguir, em Linux, onde isso acontece.


Problema com Rótulos Repetidos

global _start

section .data
nums dq 5, 6, 7, 8, 1, 2, 3, 4
numSize equ 8
count equ ($ - nums) / numSize

section .text
_start:
    mov rdi, nums
    mov rsi, count
    call max

    mov rdi, rax
    mov rax, 60
    syscall

; Função min retorna o menor valor do array
; RDI - endereço do array
; RSI - quantidade de elementos
; RAX - resultado
min:
    mov rax, [rdi]
    jmp condition
while:
    dec rsi
    cmp rax, [rdi + rsi * numSize]
    jb condition
    mov rax, [rdi + rsi * numSize]
condition:
    cmp rsi, 1
    ja while
    ret

; Função max retorna o maior valor do array
max:
    mov rax, [rdi]
    jmp condition
while:
    dec rsi
    cmp rax, [rdi + rsi * numSize]
    ja condition
    mov rax, [rdi + rsi * numSize]
condition:
    cmp rsi, 1
    ja while
    ret

O código define duas funções (min e max), ambas com os rótulos while e condition. Durante a montagem, o NASM retornará erro:

error: label `while` inconsistently redefined
info: label `while` originally defined here
error: label `condition` inconsistently redefined
info: label `condition` originally defined here

A duplicação ocorre porque o NASM trata rótulos globais como identificadores únicos dentro de todo o programa.

Solução: Rótulos Locais

Para resolver o problema, o NASM permite criar rótulos locais, que são acessíveis apenas dentro do escopo de um rótulo global (como uma função). Um rótulo local é identificado por um ponto (.) no início do nome.

Exemplo:

.while:
.condition:

Esses rótulos são “filhos” do rótulo global que os antecede.

Escopo de um Rótulo Local

func1:
.label1:

func2:
.label2:

Neste caso:

  • .label1 pertence a func1
  • .label2 pertence a func2
  • .label1 não pode ser acessado dentro de func2

Assim, cada função pode ter seus próprios rótulos internos sem risco de conflito.

Exemplo Corrigido com Rótulos Locais

global _start

section .data
nums dq 5, 6, 7, 8, 1, 2, 3, 4
numSize equ 8
count equ ($ - nums) / numSize

section .text
_start:
    mov rdi, nums
    mov rsi, count
    call max

    mov rdi, rax
    mov rax, 60
    syscall

; Função min retorna o menor valor do array
; RDI - endereço do array
; RSI - quantidade de elementos
; RAX - resultado
min:
    mov rax, [rdi]
    jmp .condition
.while:
    dec rsi
    cmp rax, [rdi + rsi * numSize]
    jb .condition
    mov rax, [rdi + rsi * numSize]
.condition:
    cmp rsi, 1
    ja .while
    ret

; Função max retorna o maior valor do array
max:
    mov rax, [rdi]
    jmp .condition
.while:
    dec rsi
    cmp rax, [rdi + rsi * numSize]
    ja .condition
    mov rax, [rdi + rsi * numSize]
.condition:
    cmp rsi, 1
    ja .while
    ret

Agora, as metainstruções .while e .condition são locais a cada função, e o código compila corretamente.

Como o NASM Interpreta os Rótulos Locais

Internamente, o NASM converte rótulos locais no formato:

nome_global.nome_local

Assim:

  • .while dentro da função min se torna min.while
  • .condition dentro da função max se torna max.condition

Por isso, não há conflitos — cada função tem seu próprio espaço de nomes.

É até possível referenciar explicitamente o nome completo de um rótulo local:

max:
    mov rax, [rdi]
    jmp max.condition   ; salto para o rótulo local com nome completo
.while:
    dec rsi
    cmp rax, [rdi + rsi * numSize]
    ja max.condition
    mov rax, [rdi + rsi * numSize]
.condition:
    cmp rsi, 1
    ja max.while
    ret

Isso deixa claro que os rótulos locais são apenas atalhos para nomes compostos.


Resumo

  • Cada programa NASM pode conter apenas um rótulo global com determinado nome.
  • Rótulos locais começam com . e são visíveis apenas dentro do escopo do rótulo global anterior.
  • Internamente, o NASM os converte em rótulo_global.rótulo_local.
  • Isso evita conflitos de nomes e torna o código modular e mais organizado.
  • Rótulos locais são especialmente úteis para estruturas repetitivas, como loops e condições dentro de funções.
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com