Multiplicação

 

 

MULTIPLICAÇÃO
MUL Multiplicar byte ou palavra não sinalizados
IMUL Multiplicar byte ou palavra inteiros
AAM Ajuste ASCII na multiplicação

 

 

 

++MUL++

 

Quando digo "sinalizado" entenda "com sinal", "positivo ou negativo".

 

 

As operações válidas para MUL e IMUL são:

 

Fonte
Registro 8 bits
Registro 16 bits
Variável 8 bits
Variável 16 bits

 

 

 

Sua sintaxe para multiplicações de 8 bits é:

 

AX = AL * operando

 

Veja este exemplo:

 

MOV    AL,25           ;operando fonte1

MOV    CL,4             ;operando fonte2

MUL    CL                 ;AX = AL * CL

                                   ;AX = 100

 

Em AX você tem o resultado dessa multiplicação.

 

Para multiplicações de 16 bits temos:

 

DX,AX = AX * operando 

 

Mas uma vez me deparo com a falta de exatidão dos meus livros de consulta,  eles dizem: "Para valores de word, o resultado encontra-se no par de registradores AX:DX." Certo...entendi tudo!

 

Na verdade "eles" querem dizer o seguinte:

 

Se a operação de multiplicação resultar num número menor que 65535, então o registro DX = 0000h e AX = resultado.

 

Se a operação de multiplicação resultar num número maior que 65535 segue-se esta lógica:

 

-enquanto    AX > 65535 faça:

            AX = AX - 65536

            DX = DX + 1

-fim_enquanto       

 

Legal! Assim fica melhor pra entender! Note este exemplo:

 

 

MOV    AX, 50000

MOV    CX,3

MUL    CX                ;AX = AX * CX

                                  ;AX = "150000" = 18928

                                  ;DX = 2

CMP    AX,18928    ;se AX for igual a 18928, vamos logo para o FIM

JE        FIM                

 

MOV    AH,1            ;se não, espera-se o pressionamento duma tecla

INT      21H             ;para só então sair.

 

FIM:

MOV    AH,4CH

INT      21H

 

 

 

++IMUL++

 

Antes de falar sobre o IMUL, tenho de apresentar dois novos tipos de dados que são: o 'sbyte' e o 'sword'. Note a tabela:

 

WORD (DW) Variável de 16 bits. Abrange valores de 0 a 65535
SWORD Variável de 16 bits. Abrange valores de -32768 a 32767
BYTE (DB) Variável de 8 bits. Abrange valores de 0 a 255
SBYTE Variável de 8 bits. Abrange valores de -128 a 127

 

 

Já sabemos o que ocorre quando ultrapassamos os valores permitidos para variáveis do tipo word e byte. Só para lembrar, são feitas subtrações sucessivas (de 65536 para DW e 256 para DB) até que a variável fique na faixa de valores permitidos para DW e DB. Mas o que ocorre com sword e sbyte, quando ultrapassamos os valores permitidos ?

 

Observe:

 

num1        sbyte    ?

 

 

mov    num1,125

add    num1,3        ;num1 = 125 + 3 = 128

 

Poderá notar, se compilar isso, que nada vai acontecer. O código ASCII de número 128 será apresentado na tela. Valendo assim as propriedades descritas no ASM1F, quando ultrapassamos o limite de variáveis DB e DW.

 

No entanto os tipos de dados sinalizados simplificam a nossa vida. Note este exemplo:

 

MOV    AX,1

SUB    AX,3        ;AX = -2

 

.IF    AX < 0

    CALL    FIM

.ENDIF

 

Isso não funciona, sabe por quê ? Lembre-se do complemento de dois, e de como os números negativos são representados. Se "0" é igual a 0000h, como é representado "-2" ? Reposta: FFFEh. Por alguma razão que não conheço, o registro não consegue comparar estes dois valores.

 

MOV    AX,1

SUB    AX,3        ;AX = -2

 

.IF    AX < -1

    CALL    FIM

.ENDIF

 

Isso sim funciona, sabe por quê ? Lembre-se do complemento de dois, e de como os números negativos são representados. Se "-1" é igual a FFFFh, como é representado "-2" ? Reposta: FFFEh. Dessa vez o registrador resolve colaborar e admitir que  -2 é menor que -1, seguindo assim a lógica matemática.

 

O mesmo aconteceria se usássemos uma variável do tipo byte. Note:

 

NATURAL        DB           ?

 

MOV    NATURAL,1

SUB    NATURAL,3        ;NATURAL=-2

 

.IF    NATURAL < 0

    CALL    FIM                ;essa rotina NUNCA será chamada!

.ENDIF

 

 

Mas podemos mudar isso:

 

MOV    NATURAL,1

SUB    NATURAL,3        ;NATURAL=-2

 

.IF    NATURAL < -1

    CALL    FIM                ;essa rotina SIM será chamada!

.ENDIF

 

 

 

No entanto se declaramos uma variável do tipo SBYTE nada disso ocorre:

 

MOV    REAL,1

SUB    REAL,3

 

.IF    REAL < 0

    CALL    FIM        ;AGORA SIM, funciona mesmo!!!

.ENDIF

 

Lembrando que tudo o que foi dito para SBYTE é válido para SWORD. 

E agora falemos finalmente do IMUL.

 

Sua sintaxe é a mesma da instrução MUL:

 

AX = AL * operando

 

Onde o operando pode ser um número sinalizado.

 

Mas o que acontece quando ultrapassa-se os limites ? Para valores maiores que 65535, o IMUL comporta-se da mesma forma que o MUL, tanto para valores positivos quanto negativos.