quinta-feira, 25 de maio de 2017

Curso de Assembly Aula 06


i-------------©
¦ ASSEMBLY VI ¦
È-------------¥

    Instruçöes aritiméticas  säo  o  tópico  de  hoje.   Já discuti,
brevemente,  os  flags  e  os  sistemas  de numeraçäo.  Aqui vai uma
aplicaçäo prática:

 ¦ Soma:

    A  soma  é  feita através das instruçöes ADD e ADC.  A diferença
entre elas é que uma faz  a  soma  normalmente e a outra faz a mesma
coisa acrecentando o conteúdo do flag CARRY. Eis a sintaxe:

 +-----------------------------------------------------------------+
 ¦  ADD AL,10h                                                     ¦
 ¦  ADC AH,22h                                                     ¦
 ¦                                                                 ¦
 ¦  ADD AX,2210h                                                   ¦
 +-----------------------------------------------------------------+

    As duas primeiras instruçöes fazem exatamente a mesma coisa  que
a  terceira.  Note que na primeiria somamos AL com 10h e o resultado
ficará em AL (se  ocorrer  "vai  um"  nesta  soma  o flag CARRY será
setado).   A  segunda  instruçäo  soma  AH  com  22h  MAIS  o  carry
resultante  da  primeira  instruçäo  e  o  resultado  ficará  em  AH
(novamente  setando  o  flag  carry  se  houver outro "vai um"!).  A
terceira instruçäo faz a mesma coisa porque soma 2210h a AX, ficando
o resultado em AX e o possível "vai um" no carry.

    Todos  os  flags  säo  afetados  após  a  execuçäo  de  uma  das
instruçöes de soma, exceto: I, D e Trap.


 ¦ Subtraçäo

    Semelhante as instruçöes  de  soma,  existem  duas instruçöes de
subtraçäo: SUB e SBB.  A  primeira  faz  a  subtraçäo  simples  e  a
segunda  faz  a  mesma  coisa subtraindo também o conteúdo prévio do
flag CARRY (como é uma subtraçäo o CARRY é conhecido como BORROW!).

    A sintaxe:

 +-----------------------------------------------------------------+
 ¦  SUB AL,1                                                       ¦
 ¦  SBB AH,0                                                       ¦
 ¦                                                                 ¦
 ¦  SUB AX,1                                                       ¦
 +-----------------------------------------------------------------+

    Como no exemplo  anterior,  as  duas  primeiras instruçöes fazem
exatamente o que a terceira faz...  Os flags afetados seguem a mesma
regra das instruçöes de soma!


 ¦ Incremento e decremento:

    As instruçöes INC e DEC säo usadas no lugar  de  ADD  e  SUB  se
quisermos incrementar ou decrementar o conteúdo de algum registrador
(ou de uma posiçäo de memória) de uma unidade. A sintaxe é simples:

 +----------------------------------------------------------------+
 ¦  DEC AX                                                        ¦
 ¦  INC BL                                                        ¦
 +----------------------------------------------------------------+

    Os  flags afetados seguem a mesma regra de uma instruçäo de soma
ou uma de subtraçäo!


 ¦ Multiplicaçäo:

    Os  processadores  da   família   80x86  possuem  instruçöes  de
multiplicaçäo e divisäo  inteiras  (ponto  flutuante fica pro 8087).
Alguns cuidados devem ser tomados quando usarmos  uma  instruçäo  de
divisäo (que será vista mais adiante!).

    Uma   coisa   interessante   com   a   multiplicaçäo  é  que  se
multiplicarmos dois registradores de  16  bits obteremos o resultado
necessariamente em 32 bits.   O  par  de  registradores  DX e AX säo
usados para armazenar esse número de 32 bits da seguinte  forma:  DX
será a word mais significativa e AX a menos significativa.

    Por exemplo, se  multiplicarmos  0FFFFh  por  0FFFFh  obteremos:
0FFFE0001h (DX = 0FFFEh e AX = 0001h).

    Eis  a  regra  para  descobrir  o  tamanho  do restultado de uma
operaçäo de multiplicaçäo:

                +---------------------------------+
                ¦             A * B = M           ¦
                +---------------------------------¦
                ¦    A     ¦     B     ¦     M    ¦
                +----------+-----------+----------¦
                ¦  8 bits  ¦   8 bits  ¦  16 bits ¦
                ¦          ¦           ¦          ¦
                ¦ 16 bits  ¦  16 bits  ¦  32 bits ¦
                +---------------------------------+

    A multiplicaçäo sempre ocorrerá entre  o acumulador (AL ou AX) e
um outro operando. Eis a sintaxe das instruçöes:

 +----------------------------------------------------------------+
 ¦  MUL BL      ; AX = AL * BL                                    ¦
 ¦  IMUL CX     ; DX:AX = AX * CX                                 ¦
 +----------------------------------------------------------------+

    A primeira instruçäo (MUL) näo considera o sinal dos  operandos.
Neste  caso, como BL é de 8 bits, a multiplicaçäo se dará entre BL e
AL e o resultado será armazenado em AX.

    A segunda instruçäo leva  em  consideraçäo o sinal dos operandos
e, como CX é de 16 bits, a multiplicaçäo se dará entre CX e AX  e  o
restultado  será armazenado em DX e AX.  Lembrando que o sinal de um
número inteiro depende do seu bit mais significativo!


 ¦ Divisäo:

    Precisamos tomar cuidado com a  divisäo pelo seguinte motivo: Se
o resultado näo couber no  registrador destino, um erro de "Division
by zero" ocorrerá  (isto  näo  está  perfeitamente  documentado  nos
diversos  manuais  que li enquanto estudava assembly 80x86...  Vim a
descobrir este 'macete' numa  antiga  ediçäo  da revista PC MAGAZINE
americana).  Outro cuidado é com o divisor...  se for 0 o mesmo erro
ocorrerá!

    A  divisäo  pode ser feita entre um número de 32 bits e um de 16
ou entre um de 16 e um de 8, veja a tabela:

                +--------------------------------+
                ¦        A / B = Q e resto       ¦
                +--------------------------------¦
                ¦    A     ¦     B     ¦Q e resto¦
                +----------+-----------+---------¦
                ¦ 32 bits  ¦  16 bits  ¦ 16 bits ¦
                ¦          ¦           ¦         ¦
                ¦ 16 bits  ¦   8 bits  ¦  8 bits ¦
                +--------------------------------+

    Assim como na multiplicaçäo  o  número  (dividendo) de 32 bits é
armazenado em DX e AX.

    Depois da divisäo o quociente é armazenado em AL e o resto em AH
(no caso de divisäo 16/8 bits) ou o quociente fica em AX e  o  resto
em DX (no caso de divisäo 32/8 bits).

    Exemplo da sintaxe:

 +-----------------------------------------------------------------+
 ¦  DIV CX      ; AX=DX:AX / CX, DX=resto                          ¦
 ¦  IDIV BL     ; AL=AX / BL, AH=resto                             ¦
 +-----------------------------------------------------------------+

    O  primeiro  caso é uma divisäo sem sinal e o segundo com sinal.
Note os divisores (CX e BL no nosso exemplo).

    Na divisäo 16/8 bits o dividendo é armazenado  em  AX  antes  da
divisäo... No caso de 32/8 bits DX e AX säo usados...

    Mais  um  detalhe:  Os  flags,  depois  de  uma multiplicaçäo ou
divisäo näo devem ser considerados.

Nenhum comentário:

Postar um comentário

Curso SANS 504 Hacker Techniques, Exploits & Incident Handling

SANS SECURITY 504 - Hacker Techniques, Exploits & Incident Handling     SANS Security 504.5.pdf13 MB     SANS Security 504.1.pdf12 M...