Montagem - Strings
Já usamos strings de comprimento variável em nossos exemplos anteriores. As strings de comprimento variável podem ter quantos caracteres forem necessários. Geralmente, especificamos o comprimento da string por uma das duas maneiras -
- Armazenar explicitamente o comprimento da corda
- Usando um personagem sentinela
Podemos armazenar o comprimento da string explicitamente usando o símbolo do contador $ location que representa o valor atual do contador local. No exemplo a seguir -
msg db 'Hello, world!',0xa ;our dear string
len equ $ - msg ;length of our dear string
$ aponta para o byte após o último caractere da variável de string msg . Portanto,$-msgdá o comprimento da corda. Também podemos escrever
msg db 'Hello, world!',0xa ;our dear string
len equ 13 ;length of our dear string
Como alternativa, você pode armazenar strings com um caractere de sentinela final para delimitar uma string em vez de armazenar o comprimento da string explicitamente. O caractere sentinela deve ser um caractere especial que não aparece em uma string.
Por exemplo -
message DB 'I am loving it!', 0
Instruções de string
Cada instrução de string pode exigir um operando de origem, um operando de destino ou ambos. Para segmentos de 32 bits, as instruções de string usam registradores ESI e EDI para apontar para os operandos de origem e destino, respectivamente.
Para segmentos de 16 bits, entretanto, os registros SI e DI são usados para apontar para a origem e o destino, respectivamente.
Existem cinco instruções básicas para o processamento de strings. Eles são -
MOVS - Esta instrução move 1 byte, palavra ou palavra dupla de dados do local da memória para outro.
LODS- Esta instrução é carregada da memória. Se o operando for de um byte, ele é carregado no registro AL, se o operando for uma palavra, ele é carregado no registro AX e uma palavra dupla é carregada no registro EAX.
STOS - Esta instrução armazena dados do registrador (AL, AX ou EAX) na memória.
CMPS- Esta instrução compara dois itens de dados na memória. Os dados podem ser de tamanho de byte, palavra ou palavra dupla.
SCAS - Esta instrução compara o conteúdo de um registro (AL, AX ou EAX) com o conteúdo de um item na memória.
Cada uma das instruções acima tem uma versão de byte, palavra e palavra dupla, e as instruções de string podem ser repetidas usando um prefixo de repetição.
Essas instruções usam o par de registradores ES: DI e DS: SI, onde os registradores DI e SI contêm endereços de deslocamento válidos que se referem aos bytes armazenados na memória. SI está normalmente associado a DS (segmento de dados) e DI está sempre associado a ES (segmento extra).
Os registradores DS: SI (ou ESI) e ES: DI (ou EDI) apontam para os operandos fonte e destino, respectivamente. Supõe-se que o operando de origem esteja em DS: SI (ou ESI) e o operando de destino em ES: DI (ou EDI) na memória.
Para endereços de 16 bits, os registros SI e DI são usados, e para endereços de 32 bits, os registros ESI e EDI são usados.
A tabela a seguir fornece várias versões de instruções de string e o espaço assumido dos operandos.
Instrução Básica | Operandos em | Operação de Byte | Operação de Palavra | Operação de palavra dupla |
---|---|---|---|---|
MOVS | ES: DI, DS: SI | MOVSB | MOVSW | MOVSD |
LODS | AX, DS: SI | LODSB | LODSW | LODSD |
STOS | ES: DI, AX | STOSB | STOSW | STOSD |
CMPS | DS: SI, ES: DI | CMPSB | CMPSW | CMPSD |
SCAS | ES: DI, AX | SCASB | SCASW | SCASD |
Prefixos de repetição
O prefixo REP, quando definido antes de uma instrução de string, por exemplo - REP MOVSB, causa a repetição da instrução com base em um contador colocado no registrador CX. REP executa a instrução, diminui CX em 1 e verifica se CX é zero. Ele repete o processamento da instrução até que CX seja zero.
A Bandeira de Direção (DF) determina a direção da operação.
- Use CLD (Clear Direction Flag, DF = 0) para fazer a operação da esquerda para a direita.
- Use STD (Definir Bandeira de Direção, DF = 1) para fazer a operação da direita para a esquerda.
O prefixo REP também tem as seguintes variações:
REP: É a repetição incondicional. Ele repete a operação até que CX seja zero.
REPE ou REPZ: É uma repetição condicional. Ele repete a operação enquanto o sinalizador zero indica igual / zero. Pára quando ZF indica diferente de / zero ou quando CX é zero.
REPNE ou REPNZ: também é uma repetição condicional. Ele repete a operação enquanto o sinalizador zero indica diferente de / zero. Ele para quando ZF indica igual / zero ou quando CX é decrementado para zero.