Comparação de Strings em Assembly NASM
Para comparar strings em Assembly NASM, o processador x86-64 fornece um conjunto de instruções específicas, de acordo com o tamanho dos elementos que compõem a string:
| Instrução | Tipo de dado comparado |
|---|---|
| CMPSB | String de bytes (8 bits) |
| CMPSW | String de palavras (16 bits) |
| CMPSD | String de palavras duplas (32 bits) |
| CMPSQ | String de palavras quádruplas (64 bits) |
Essas instruções comparam o valor apontado por RDI (destino) com o valor apontado por RSI (origem). O registrador RCX contém a quantidade de elementos a comparar (não o número de bytes).
Após cada comparação, os registradores RSI e RDI são ajustados (incrementados ou decrementados) conforme o tamanho do elemento e o estado do flag de direção (DF).
Prefixos de Repetição
As instruções de comparação podem ser combinadas com prefixos que controlam o comportamento do laço:
| Prefixo | Descrição |
|---|---|
| REPE ou REPZ | Repete enquanto os elementos forem iguais e RCX ≠ 0. Usado com strings de caracteres. |
| REPNE ou REPNZ | Repete enquanto os elementos forem diferentes e RCX ≠ 0. |
Sem prefixo, a instrução CMPS realiza uma única comparação, ajusta os registradores e atualiza os flags.
Exemplo: Comparação de Arrays Numéricos
O exemplo abaixo compara dois vetores de 8 palavras. Se forem iguais, RDI = 4; caso contrário, RDI = 2.
global _start
section .data
nums1 dw 10, 11, 12, 13, 14, 15, 16, 17
nums2 dw 10, 11, 12, 13, 14, 15, 16, 17
section .text
_start:
mov rsi, nums1
mov rdi, nums2
mov rcx, 8 ; número de palavras
repe cmpsw ; compara elemento a elemento
jz equal ; se iguais, salta para equal
mov rdi, 2 ; diferentes
jmp exit
equal:
mov rdi, 4 ; iguais
exit:
mov rax, 60
syscallA instrução repe cmpsw compara os pares de palavras até encontrar uma diferença ou até RCX = 0.
Comparação de Strings de Comprimentos Diferentes
Quando as strings podem ter tamanhos diferentes, a comparação deve considerar tanto os conteúdos quanto as comprimentos.
- Duas strings são iguais se têm o mesmo tamanho e os mesmos caracteres.
- Se uma é menor, mas todos os seus caracteres coincidem com o início da outra, considera-se que ela é menor.
O exemplo a seguir compara duas strings de texto:
global _start
section .data
str1 db "Hello World"
str1_len equ $-str1
str2 db "Hello World"
str2_len equ $-str2
section .text
_start:
mov rsi, str1
mov rdi, str2
mov rcx, str1_len
cmp rcx, str2_len ; compara tamanhos
jbe compare ; se str1 ≤ str2
mov rcx, str2_len ; usa o menor tamanho
compare:
repe cmpsb ; compara byte a byte
jnz notequal ; se diferente
mov rcx, str1_len
cmp rcx, str2_len ; compara tamanhos finais
jnz notequal
mov rdi, 16 ; iguais
jmp exit
notequal:
mov rdi, 8 ; diferentes
exit:
mov rax, 60
syscallO prefixo repe garante que o processador compare todos os bytes até encontrar uma diferença ou até o fim da menor string.
A comparação de caracteres é feita com base em seus códigos ASCII — logo, o resultado reflete a ordem alfabética natural.
Resumo
- O processador x86-64 oferece instruções CMPSB, CMPSW, CMPSD e CMPSQ para comparar strings.
- Os registradores usados são RSI (origem), RDI (destino) e RCX (contador).
- O prefixo REPE repete enquanto os elementos forem iguais; REPNE, enquanto forem diferentes.
- O flag de direção (DF) define o sentido da leitura: crescente (
cld) ou decrescente (std). - A comparação entre caracteres segue a ordem ASCII — útil para ordenações e buscas textuais.