Busca em Strings em Assembly NASM
Para localizar um elemento específico dentro de uma string em Assembly NASM, o processador x86-64 oferece as seguintes instruções:
| Instrução | Tipo de dado pesquisado |
|---|---|
| SCASB | Byte (8 bits) |
| SCASW | Palavra (16 bits) |
| SCASD | Palavra dupla (32 bits) |
| SCASQ | Palavra quádrupla (64 bits) |
Essas instruções comparam o valor armazenado em AL, AX, EAX ou RAX com o elemento apontado por RDI. Após cada comparação, o processador ajusta o endereço em RDI (incrementando ou decrementando conforme o tamanho do elemento) e atualiza os flags de acordo com o resultado.
Se o elemento for encontrado, o flag ZF (Zero Flag) é definido, e RDI passa a apontar para o próximo elemento após o encontrado.
Prefixos de Repetição
As instruções SCAS podem ser combinadas com prefixos que controlam o comportamento do laço:
| Prefixo | Descrição |
|---|---|
| REPE | Repete enquanto os elementos forem iguais. |
| REPNE | Repete enquanto os elementos forem diferentes (usado em buscas). |
Durante a execução, o registrador RCX define quantos elementos (e não bytes) serão examinados.
Exemplo: Busca de um Caractere em uma String
O programa abaixo procura o caractere “l” na string “Hello”. Caso encontrado, o índice é calculado e armazenado em RDI.
global _start
section .data
message db "Hello" ; string base
len equ $-message ; comprimento da string
char db "l" ; caractere procurado
section .text
_start:
mov rdi, message ; endereço da string
mov al, [char] ; caractere alvo
mov rcx, len ; número de caracteres
repne scasb ; busca até encontrar ou esgotar RCX
jz found ; se encontrado, ZF = 1
mov rdi, -1 ; se não encontrado
jmp exit
found:
sub rdi, message ; diferença = índice + 1
dec rdi ; ajusta: índice exato do caractere
exit:
mov rax, 60
syscallAqui, scasb compara o byte em AL com cada byte da string.
Se o caractere for encontrado, ZF é ativado, e RDI apontará para o próximo endereço após o caractere encontrado.
A diferença rdi - message fornece a posição relativa (índice), e o dec rdi corrige para o índice exato.
Por exemplo, na palavra “Hello”, o caractere “l” aparece na posição 2 (terceiro caractere).
Se o símbolo não for encontrado, RDI recebe -1.
Exemplo: Descobrindo o Tamanho de uma String
A instrução SCASB também pode ser usada para medir o comprimento de uma string terminada por byte nulo (0x00).
global _start
section .data
message db "Hello programicio.com", 0 ; string com byte nulo final
section .text
_start:
mov rdi, message ; endereço inicial
mov al, 0 ; caractere buscado: byte nulo
mov rcx, -1 ; máximo possível (interpreta-se como "infinito")
repne scasb ; busca até encontrar o byte nulo
sub rdi, message ; diferença = índice + 1
dec rdi ; índice do byte nulo = tamanho da string
mov rax, 60
syscallComo não sabemos o tamanho da string, o valor -1 em RCX define um limite enorme — o processador vai interromper a busca assim que encontrar o byte nulo.
O resultado em RDI (após ajuste) indica o número de caracteres da string.
Resumo
- As instruções SCASB, SCASW, SCASD e SCASQ realizam buscas em strings.
- RDI aponta para a string pesquisada; AL/AX/EAX/RAX contém o valor a ser encontrado.
- RCX define o número de elementos a examinar.
- REPNE repete até achar o valor procurado ou até RCX = 0.
- ZF (Zero Flag) indica sucesso na busca.
- O resultado final pode ser usado para calcular o índice do elemento encontrado.