>> Tecnologia Eletrônica >  >> Áudio Residencial >> Amplificadores

Instrução IMUL no 8086: Mecânica da Multiplicação com Sinal

A instrução IMUL (Integer Multiply) no 8086/8088 realiza multiplicação com sinal de operandos de 8 ou 16 bits. É distinta de MUL (multiplicação sem sinal). Aqui está a operação precisa:

Formas da Instrução (8086/8088)

FormaSintaxeOperaçãoTamanho do ResultadoFlags Afetadas
8 bitsIMUL r/m8AL × r/m816 bits em AXCF, OF (set se AH com sinal estendido ≠ AL); SF, ZF, AF, PF indefinidas
16 bitsIMUL r/m16AX × r/m1632 bits em DX:AXCF, OF (set se DX com sinal estendido ≠ AX); SF, ZF, AF, PF indefinidas

r/m8 = registrador ou memória de 8 bits; r/m16 = registrador ou memória de 16 bits.

Execução Passo a Passo (Exemplo Forma 16 bits)

  1. Operandos: Fonte (registrador/memória) e destino implícito AX.
  2. Extensão de Sinal: Ambos operandos tratados como inteiros com sinal em complemento de 2.
  3. Multiplicação: ALU calcula AX × src como produto com sinal de 32 bits.
  4. Armazenamento do Resultado:
    • 16 bits inferiores → AX
    • 16 bits superiores → DX
  5. Definição de Flags:
    • CF = OF = 1 se palavra alta (DX) não for extensão de sinal da palavra baixa (AX). Ou seja, se resultado não couber em 16 bits com sinal.
    • CF = OF = 0 se resultado couber em 16 bits (DX = extensão de sinal de AX).
    • SF, ZF, AF, PF são indefinidas (conforme manual Intel). Não confie nelas.

Regra de Extensão de Sinal

Para um resultado de 16 bits em AX ser "corretamente com sinal", os 16 bits superiores (DX) devem ser todos 0s (se positivo) ou todos 1s (se negativo) — ou seja, DX = AX replicado para 16 bits. Se não, ocorreu overflow.

Exemplo: IMUL 16 bits

 ; AX = 0x23AF (9.135), src = 0x4567 (17.767) ; Produto = 9.135 × 17.767 = 162.300.345 = 0x09B3 0x10B9 (32 bits) ; DX:AX = 0x09B3:0x10B9 ; Como DX (0x09B3) ≠ extensão de sinal de AX (0x10B9 → bit de sinal 0 → DX deveria ser 0x0000), ; CF=1, OF=1 (overflow: resultado > 32.767) 

Exemplo 8 bits

 ; AL = 0x7F (127), BL = 0x02 (2) ; IMUL BL ; AX = 0x00FA (254) → cabe em 8 bits com sinal? 254 > 127 → overflow. ; AH = 0x00, AL = 0xFA. AH (0x00) ≠ ext. de sinal de AL (0xFA → bit sinal 1 → AH deveria ser 0xFF). ; CF=1, OF=1. 

Diferenças Principais: IMUL vs. MUL

  • MUL: Sem sinal. Trata operandos como positivos. CF/OF set se resultado > tamanho destino (ex.: AX > FFh para 8 bits).
  • IMUL: Com sinal. Trata operandos como complemento de 2. CF/OF set se resultado não couber no tamanho destino com sinal.

Extensões Posteriores (186+ / 386+)

  • Dois operandos: IMUL r16, r/m16 → r16 = r16 × r/m16 (apenas 16 bits baixos, sem DX).
  • Três operandos: IMUL r16, r/m16, imm16 → r16 = r/m16 × imm16.
  • Formas imediatas: IMUL r16, imm8/imm16.
  • Estas truncam para 16 bits; CF/OF set se bits truncados ≠ bits de sinal.

Notas Práticas

  • IMUL é mais lento que MUL (lógica extra de sinal). ~80–130 ciclos no 8086.
  • Use CBW (AL→AX) / CWD (AX→DX:AX) antes de IMUL se estender tamanho do operando.
  • Para 8 bits × 8 bits → 16 bits no 8086, resultado sempre em AX. DX não usado.
  • Em assembly inline (C), use intrínsecos ou built-ins do compilador (__emulu, __emuls).

IMUL é essencial para aritmética em inteiros com sinal (coordenadas, física, DSP, cripto) em código real-mode de 16 bits.