Instruções de Deslocamento

Instruções Significado Sintaxe Operação Flags Afetados
SAL / SHL Deslocamento lógico/aritmético a esquerda

SAL D, contador

ou

SHL D, contador

Deslocar (D) a esquerda pelo número de posições de bit indicado pelo contador, preenchendo as posições livres a direita com zeros

 

OF, CF
SHR Deslocamento lógico a direita SHR D, contador

Desloca (D) a direita pelo numero de posições de bit indicado pelo contador, preenchendo as posições livres a esquerda com zeros

 

OF, CF
SAR Deslocamento aritmético a direita SAR D, contador

Deslocar (D) a direita pelo número de posições de bit indicado pelo contador, preenchendo as posições a esquerda com o valor original do bit de maior peso(mais significativo).

 

OF, SF, ZF, AF, PF, CF

 

 

MOV   AX, 01001101B    ;AX = 4Dh

SAL   AX, 1            ;SAL ou SHR executado pela 1ª vez

 

                                  MSB                                                                                                LSB

AX = 4Dh   0 1 0 0 1 1 0 1

                                  /              /              /              /              /              /              /              /

                               /              /              /              /              /              /              /              /

                            /              /              /              /              /              /              /              /

CF = 0   1 0 0 1 1 0 1 0
  AX = 9 A

 

Observe que 9Ah = 2*4Dh

 

 

SAL   AX, 1            ;SAL executado pela 2ª vez

 

                                  MSB                                                                                                LSB

AX = 9Ah   1 0 0 1 1 0 1 0

                                  /              /              /              /              /              /              /              /

                               /              /              /              /              /              /              /              /

                            /              /              /              /              /              /              /              /

CF = 1   0 0 1 1 0 1 0 0
  AX = 3 4

 

 

Observe que  134h = CF + 34h = 2*9Ah

 

SAL   AX, 1            ;SAL executado pela 3ª vez

 

                                  MSB                                                                                                LSB

AX = 9Ah   0 0 1 1 0 1 0 0

                                  /              /              /              /              /              /              /              /

                               /              /              /              /              /              /              /              /

                            /              /              /              /              /              /              /              /

CF = 0   0 1 1 0 1 0 0 0
  AX = 6 8

 

Observe que 68h = 2*34h

 

SAL   AX, 1            ;SAL executado pela 4ª vez

 

                                  MSB                                                                                                LSB

AX = 9Ah   0 1 1 0 1 0 0 0

                                  /              /              /              /              /              /              /              /

                               /              /              /              /              /              /              /              /

                            /              /              /              /              /              /              /              /

CF = 0   1 1 0 1 0 0 0 0
  AX = D 0

 

Observe que 0D0h = 2*68h

 

Note que LSB significa bit menos significativo(de menor peso) e MSB bit mais significativo(de maior peso). Conforme visto, usando-se SAL ou SHL, os bits vagos a direita são preenchidos com zeros, enquanto o flag de carry(CF) assume o valor do bit MSB. 

 

Depois de quatro "observe" deve ter percebido que o SAL ou SHL estavam multiplicando o valor do operando destino por 2, a cada vez que um bit zero ocupava uma posição a esquerda. Note agora um exemplo diferente:

 

MOV   AX, 1010B    ;AX = 0Ah

SAL   AX, 1            ;SAL ou SHR executado pela 1ª vez

 

                                  MSB                                                                                                LSB

AX = 4Dh   0 0 0 0 1 0 1 0

                                  /              /              /              /              /              /              /              /

                               /              /              /              /              /              /              /              /

                            /              /              /              /              /              /              /              /

CF = 0   0 0 0 1 0 1 0 0
  AX = 1 4

 

Observe que 14h = 2*0Ah

 

 

MOV   CL, 2

MOV   AX, 1010B

SAL   AX, CL            ;SAL executado pela 2ª vez

 

                                  MSB                                                                                                LSB

AX = 0Ah   0 0 0 0 1 0 1 0

                                  /              /              /              /              /              /              /              /

                               /              /              /              /              /              /              /              /

                            /              /              /              /              /              /              /              /

CF = 0   0 0 0 1 0 1 0 0

                                  /              /              /              /              /              /              /              /

                               /              /              /              /              /              /              /              /

                            /              /              /              /              /              /              /              /

CF = 0   0 0 1 0 1 0 0 0
  AX = 2 8

 

Observe que 28h = 4*0Ah

 

 

MOV   CL, 3

MOV   AX, 1010B

SAL   AX, CL            ;SAL executado pela 2ª vez

 

                                  MSB                                                                                                LSB

AX = 0Ah   0 0 0 0 1 0 1 0

                                  /              /              /              /              /              /              /              /

                               /              /              /              /              /              /              /              /

                            /              /              /              /              /              /              /              /

CF = 0   0 0 0 1 0 1 0 0

                                  /              /              /              /              /              /              /              /

                               /              /              /              /              /              /              /              /

                            /              /              /              /              /              /              /              /

CF = 0   0 0 1 0 1 0 0 0

                                  /              /              /              /              /              /              /              /

                               /              /              /              /              /              /              /              /

                            /              /              /              /              /              /              /              /

CF = 0   0 1 0 1 0 0 0 0
  AX = 5 0

 

Observe que 50h = 8*0Ah

 

Se fizer isso N vezes irá notar que:

AX = 2^N * AX -->

AX = 2^CL * AX

 

Onde CL, e apenas CL ou CX(sendo que CX <= 256), é o contador. AX representa, nesse exemplo o operando destino. A sintaxe correta para as instruções deslocamento é mostrada abaixo:

 

Destino contador
registro 1
registro CL
memória 1
memória CL

 

 

Resumindo tudo nós notamos o seguinte:

 

A dupla SAL / SHL realizam uma multiplicação do tipo: Destino = Destino * 2^CL

E SAR / SHR realizam uma divisão do tipo: Destino = Destino / (2^CL)

 

"E qual a diferença entre SAL e SHL ?" Nenhuma, ambos realizam a mesma função e com a mesma performance. A lógica de ambas é seguinte:

 

+----+     +---------+
¦ CF ¦ <-- ¦ Destino ¦ <-- 0
+----+     +---------+

 

Já a "dupla de dois" SAR e SHR são diferentes. Note a lógica de cada uma delas:

 

SAR:


+----+     +---------+     +----+
¦ SF ¦ --> ¦ DESTINO ¦ --> ¦ CF ¦
+----+     +---------+     +----+

 

SHR:

      +---------+     +----+
0 --> ¦ Destino ¦ --> ¦ CF ¦
      +---------+     +----+

Uma coisa é certa, as duas realizam uma instrução de divisão, mas a diferença está em como cada uma lida com números sinalizados. SAR realiza uma divisão do tipo Destino = Destino / (2^CL),  mantendo o sinal do operando destino. Enquanto SHR, faz a divisão de números não sinalizados.

Se quer ver a prova, observe:

MOV    NUM2, -10        ;-10 = 0FFF6h

SHR    NUM2, 1           ;-10 / 2 = 5 = 7FFBh

                                  ;esse numero é positivo!!!

;

;NUM2 = 7FFBh           ;lembre-se, isso é bem básico, o se o bit MSB for 0

;                                  ;o número será POSITIVO.

 

MOV    NUM2, -10        ;-10 = 0FFF6h

SAR    NUM2, 1           ;-10 / 2 = -5 = 0FFFBh

                                  ;esse número é NEGATIVO

;

;NUM2 = FFFBh           ;lembre-se, isso é bem básico, o se o bit MSB for 1

;                                 ;o número será NEGATIVO.

 

Caso não esteja acreditando, acrescente um NEG no código veja se o que acontece:

 

 

MOV    NUM2, -10          ;-10 = 0FFF6h

SHR    NUM2, 1             ;-10 / 2 = 5 = 7FFBh

                                    ;esse numero é positivo!!!

NEG    NUM2                ;NUM2 = 1000 0000 0000 0101b

                                    ;antes do NEG, era "0", portanto, era POSITIVO

 

;

;NUM2 = 8005h            ;lembre-se, isso é bem básico, o se o bit MSB for 0

;                                  ;o número será POSITIVO.

 

MOV    NUM2, -10       ;-10 = 0FFF6h

SAR    NUM2, 1           ;-10 / 2 = -5 = 0FFFBh

                                  ;esse número é NEGATIVO

NEG    NUM2              ;NUM2 = 0000 0000 0000 0101b

                                  ;antes do NEG, era "1", portanto, era NEGATIVO

;

;NUM2 = 0005h           ;lembre-se, isso é bem básico, o se o bit MSB for 1

;                                 ;o número será NEGATIVO.

 

 

Quando tiver que multiplicar operandos por números que são potência de 2, é mais rápido fazê-lo usando SAL ou SHL. Para que tenha um idéia disso, o Norton Guide nos mostra quantos cloks são gastos usando-se cada instrução:

 

SAL ou SHR

 

 

 

 

MUL

 

 

 

Conforme visto, usar um SAL ou SHL para multiplicar um operando por um número que é potência de 2 é, no mímino, 35 vezes mais rápido que usar o MUL. O mesmo raciocínio é válido para SHR e SAR em comparação com DIV.

 

Para aprender a usar as instruções de deslocamento, baixe o asml_1.zip e modifique a linha 82 pela instrução que deseja estudar. Salve e compile, lembrando que este código faz uso das rotinas do AsmBR. 

 

 

 

Instruções de Rotação

 

 

Instruções Significado Sintaxe Operação Flags Afetados
ROL Rotação a esquerda

ROL D, contador

Rotacionar (D) a esquerda bit a bit pelo número de vezes indicado pelo contador. O bit deslocado retorna a posição mais a direita.

OF, CF
ROR Rotação a direita ROR D, contador Rotacionar (D) a direita bit a bit pelo número de vezes indicado pelo contador. O bit deslocado retorna a posição mais a esquerda OF, CF
RCL Rotação a esquerda através do transporte(carray) RCL D, contador O mesmo que ROL, porém utilizando o bit de carry. OF, CF
RCR Rotação a direita através do transporte(carray) RCR D, contador O mesmo que ROR, porém utilizando o bit de carry. OF, CF

 

 

Sintaxe das instruções

 

Destino Contador
Registro 1
Registro CL
Memória 1
Memória CL

 

 

Note agora os exemplos:

 

ROL

 

Sua lógica é a seguinte:

 

 

 

 

Perceba que o valor do bit mais significativo do "destino" é "jogado" no flag de carry e não é alterado, não importa quantas rotações tenham sido feitas.

 

 

 

 

 

A instrução ROL irá rotacionar todos os bits, começando pelo bit 0, para a esquerda. Neste exemplo vou rotacionar 2 bits. Note:

 

 

 

Observou que o número 9 foi "empurrado duas casas" para a frente(esquerda)? Agora execute novamente o programa e escolha o mesmo número 9 e rotacione agora 15. Percebeu o que está acontecendo? o bit de valor 1, menos significativo, foi empurrado dois bits para frente. Baixar asml_2.zip

 

 

 

RCL

 

A instrução RCL irá rotacionar todos os bits, começando pelo bit 0, para a esquerda, incluindo o bit presente no flag de carry. Sua lógica é a seguinte:

 

 

 

 

Perceba que o bit mais significativo do "destino" é jogado no flag de carry. Este, por sua vez, realimenta o "destino" pela esquerda.

 

 

 

 

 Neste exemplo vou rotacionar 2 bits. Note:

 

 

 

Observou que o número 9 foi "empurrado duas casas" para a frente(esquerda), juntamente com o bit que havia no flag de carry? Se o bit do flag de carry fosse zero, o resultado seria o mesmo se usássemos ROL. Baixar asml_3.zip

 

 

 

 

 

ROR

Sua lógica é a seguinte:

 

 

 

Perceba que o valor do bit menos significativo do "destino" é "jogado" no flag de carry. E este não se altera, não importa quantas rotações tenham sido feitas.

 

 

 

A instrução ROR irá rotacionar todos os bits, começando pelo bit 0, para a direita Neste exemplo vou rotacionar 2 bits. Note:

 

 

 

Observou que o número 9 foi "empurrado duas casas" para a trás(direita)?  Agora execute novamente o programa e escolha o mesmo número 9 e rotacione agora 5. Percebeu o que está acontecendo? o bit de valor 1, menos significativo, foi empurrado dois bits para frente. Baixar asml_4.zip

 

 

 

 

RCR

 

Sua lógica é a seguinte:

 

 

Perceba que o valor do bit menos significativo é "jogado" no flag de carry, este, por sua vez, é realimenta o "destino" pela direita.

 

 

 

A instrução RCR irá rotacionar todos os bits, começando pelo bit 0, para a direita, incluindo o valor do bit do flag de carry. Neste exemplo vou rotacionar 2 bits. Note:

 

 

 

Observou que o número 9 foi "empurrado duas casas" para a trás(direita), juntamente com o bit que havia no flag de carry? Se o bit do flag de carry fosse zero, o resultado seria o mesmo se usássemos ROR. Baixar asml_5.zip