Sobre a instrução test... #27

Open
opened 2025-07-29 05:50:57 -03:00 by leandrossantos · 0 comments

A instrução test em assembly x86-64 afeta a flag SF (Sign Flag) de maneira direta, baseando-se no resultado da operação lógica que ela executa.

Para entender o processo, vamos detalhar o que a instrução test faz.

O que a instrução test faz?

A instrução test executa uma operação AND lógica bit a bit entre dois operandos (por exemplo, test rax, rbx). O resultado dessa operação AND não é armazenado em nenhum dos operandos. O único propósito da instrução test é definir as flags de status (SF, ZF, PF) de acordo com o resultado dessa operação lógica.

Como a SF (Sign Flag) é afetada?

A SF (Sign Flag) é uma das flags de status no registrador RFLAGS. Sua função é indicar o sinal do resultado de uma operação aritmética ou lógica.

  1. A SF é uma cópia do bit mais significativo (MSB) do resultado.
  2. Se o bit mais significativo do resultado for 1, a SF será definida como 1 (indicando um número negativo em notação de complemento de dois).
  3. Se o bit mais significativo do resultado for 0, a SF será definida como 0 (indicando um número positivo).

Portanto, a instrução test afeta a SF da seguinte forma:

A instrução test calcula o AND lógico entre seus operandos e, em seguida, define a flag SF com o valor do bit mais significativo (o bit de sinal) desse resultado.

Exemplos Práticos

Vamos ver como isso funciona com exemplos em 64 bits. O bit mais significativo em um registrador de 64 bits é o bit 63.

Exemplo 1: Resultado Positivo (SF = 0)

Vamos testar um número positivo.

  • rax = 0x7000000000000000 (um número positivo, pois o bit 63 é 0)
  • rbx = 0xFFFFFFFFFFFFFFFF (todos os bits são 1)
test rax, rbx
  1. Operação AND: 0x7000... AND 0xFFFF... resulta em 0x7000....
  2. Resultado: 0x7000000000000000.
  3. Bit mais significativo (bit 63): O bit 63 deste resultado é 0.
  4. Efeito na Flag: A SF será definida como 0.

Exemplo 2: Resultado Negativo (SF = 1)

Agora, vamos testar um número negativo.

  • rax = 0x9000000000000000 (um número negativo, pois o bit 63 é 1)
  • rbx = 0xFFFFFFFFFFFFFFFF
test rax, rbx
  1. Operação AND: 0x9000... AND 0xFFFF... resulta em 0x9000....
  2. Resultado: 0x9000000000000000.
  3. Bit mais significativo (bit 63): O bit 63 deste resultado é 1.
  4. Efeito na Flag: A SF será definida como 1.

Exemplo 3: Uso Comum - Testando o sinal de um único valor

Um uso muito comum da instrução test é verificar se um número é positivo, negativo ou zero, testando o registrador contra ele mesmo.

test rax, rax
  • Operação AND: rax AND rax sempre resulta no próprio valor de rax.
  • Efeito: As flags são definidas com base no valor de rax.
    • Se rax for negativo (ex: 0x8...), o resultado terá o bit de sinal 1, e a SF será 1.
    • Se rax for positivo (ex: 0x7...), o resultado terá o bit de sinal 0, e a SF será 0.
    • Se rax for zero, o resultado será zero, e a ZF (Zero Flag) será 1.

Após a instrução test rax, rax, você pode usar instruções de salto condicional como:

  • js (Jump if Sign): Salta se SF for 1 (número negativo).
  • jns (Jump if Not Sign): Salta se SF for 0 (número positivo ou zero).
  • jz (Jump if Zero): Salta se ZF for 1 (número é zero).

Resumo

Instrução Operação Interna Resultado da Operação Efeito na SF
test op1, op2 resultado = op1 AND op2 O resultado é descartado SF recebe o valor do bit mais significativo do resultado
A instrução `test` em assembly x86-64 afeta a flag `SF` (Sign Flag) de maneira direta, baseando-se no resultado da operação lógica que ela executa. Para entender o processo, vamos detalhar o que a instrução `test` faz. ### O que a instrução `test` faz? A instrução `test` executa uma operação **`AND` lógica bit a bit** entre dois operandos (por exemplo, `test rax, rbx`). O resultado dessa operação `AND` **não é armazenado** em nenhum dos operandos. O único propósito da instrução `test` é definir as flags de status (`SF`, `ZF`, `PF`) de acordo com o resultado dessa operação lógica. ### Como a `SF` (Sign Flag) é afetada? A `SF` (Sign Flag) é uma das flags de status no registrador `RFLAGS`. Sua função é indicar o sinal do resultado de uma operação aritmética ou lógica. 1. **A `SF` é uma cópia do bit mais significativo (MSB) do resultado.** 2. Se o bit mais significativo do resultado for **1**, a `SF` será definida como **1** (indicando um número negativo em notação de complemento de dois). 3. Se o bit mais significativo do resultado for **0**, a `SF` será definida como **0** (indicando um número positivo). **Portanto, a instrução `test` afeta a `SF` da seguinte forma:** > A instrução `test` calcula o `AND` lógico entre seus operandos e, em seguida, define a flag `SF` com o valor do bit mais significativo (o bit de sinal) desse resultado. ### Exemplos Práticos Vamos ver como isso funciona com exemplos em 64 bits. O bit mais significativo em um registrador de 64 bits é o bit 63. **Exemplo 1: Resultado Positivo (SF = 0)** Vamos testar um número positivo. * `rax` = `0x7000000000000000` (um número positivo, pois o bit 63 é 0) * `rbx` = `0xFFFFFFFFFFFFFFFF` (todos os bits são 1) ```assembly test rax, rbx ``` 1. **Operação `AND`:** `0x7000... AND 0xFFFF...` resulta em `0x7000...`. 2. **Resultado:** `0x7000000000000000`. 3. **Bit mais significativo (bit 63):** O bit 63 deste resultado é **0**. 4. **Efeito na Flag:** A `SF` será definida como **0**. **Exemplo 2: Resultado Negativo (SF = 1)** Agora, vamos testar um número negativo. * `rax` = `0x9000000000000000` (um número negativo, pois o bit 63 é 1) * `rbx` = `0xFFFFFFFFFFFFFFFF` ```assembly test rax, rbx ``` 1. **Operação `AND`:** `0x9000... AND 0xFFFF...` resulta em `0x9000...`. 2. **Resultado:** `0x9000000000000000`. 3. **Bit mais significativo (bit 63):** O bit 63 deste resultado é **1**. 4. **Efeito na Flag:** A `SF` será definida como **1**. **Exemplo 3: Uso Comum - Testando o sinal de um único valor** Um uso muito comum da instrução `test` é verificar se um número é positivo, negativo ou zero, testando o registrador contra ele mesmo. ```assembly test rax, rax ``` * **Operação `AND`:** `rax AND rax` sempre resulta no próprio valor de `rax`. * **Efeito:** As flags são definidas com base no valor de `rax`. * Se `rax` for negativo (ex: `0x8...`), o resultado terá o bit de sinal 1, e a **`SF` será 1**. * Se `rax` for positivo (ex: `0x7...`), o resultado terá o bit de sinal 0, e a **`SF` será 0**. * Se `rax` for zero, o resultado será zero, e a **`ZF` (Zero Flag) será 1**. Após a instrução `test rax, rax`, você pode usar instruções de salto condicional como: * `js` (Jump if Sign): Salta se `SF` for 1 (número negativo). * `jns` (Jump if Not Sign): Salta se `SF` for 0 (número positivo ou zero). * `jz` (Jump if Zero): Salta se `ZF` for 1 (número é zero). ### Resumo | Instrução | Operação Interna | Resultado da Operação | Efeito na `SF` | | :--- | :--- | :--- | :--- | | `test op1, op2` | `resultado = op1 AND op2` | O resultado é descartado | `SF` recebe o valor do bit mais significativo do `resultado` |
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: blau_araujo/pbn#27
No description provided.