Obtenção do Endereço Atual em Assembly NASM
Em Assembly NASM, o operador $ é utilizado para obter o endereço atual dentro da seção onde o código ou os dados estão sendo definidos.
Por exemplo:
currentAddr dq $Aqui, a variável currentAddr armazena o seu próprio endereço na memória.
Essa variável pode ser manipulada como qualquer outra — é possível realizar cálculos e acessar posições relativas a ela.
O exemplo a seguir mostra uma forma prática de acessar um valor anterior ao endereço atual (Linux):
global _start
section .data
nums dq 112, 113, 114, 115, 116 ; array de números qword
currentAddr dq $
section .text
_start:
mov rdi, [currentAddr - 8] ; RDI = 116
mov rax, 60
syscallA expressão [currentAddr - 8] acessa o valor 8 bytes antes da posição da variável currentAddr,
ou seja, o último elemento do array nums, que é o número 116.
Cálculo de Tamanho de Arrays com o Endereço Atual
O operador $ também é útil para determinar o tamanho de uma sequência de dados,
como o comprimento de um array ou de uma string.
Embora o tamanho possa ser definido manualmente, esse método elimina erros de contagem, pois calcula o tamanho automaticamente com base na posição atual no código.
global _start
section .data
nums dq 112, 113, 114, 115, 116
numsLength equ $ - nums ; armazena o tamanho do array nums
section .text
_start:
mov rdi, numsLength ; RDI = 40
mov rax, 60
syscallA expressão $ - nums subtrai o endereço de nums do endereço atual,
resultando no tamanho total do array em bytes.
Como o array possui 5 números de 8 bytes, o valor armazenado é 40.
O tamanho é uma constante e, portanto, definido com equ (equate).
Contagem de Elementos em Arrays
Para determinar quantos elementos existem no array, basta dividir o tamanho total pelo tamanho de cada elemento.
global _start
section .data
nums dq 112, 113, 114, 115, 116
numsCount equ ($ - nums) / 8 ; número de elementos do array nums
section .text
_start:
mov rdi, numsCount ; RDI = 5
mov rax, 60
syscallComo cada elemento ocupa 8 bytes, o resultado é 5 elementos.
A definição:
numsCount equ ($ - nums) / 8é avaliada em tempo de montagem, antes da execução do programa.
Exemplo em Windows
O mesmo princípio se aplica ao Windows:
global _start
section .data
nums dq 112, 113, 114, 115, 116
numsCount equ ($ - nums) / 8
section .text
_start:
mov rax, numsCount ; RAX = 5
retResumo
- O operador
$retorna o endereço atual no código ou nos dados. - Pode ser usado para obter o endereço de variáveis ou calcular distâncias entre elas.
- A expressão
$ - nomedetermina o tamanho de um bloco de dados em bytes. - A expressão
($ - nome) / tamanho_elementocalcula o número de elementos em um array. - As expressões com
equsão resolvidas em tempo de montagem (não durante a execução).