A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Informática Numaboa - Tutoriais e Programação

Cap. III - Registradores do Microprocessador

Sab

15

Dez

2007


13:46

(11 votos, média 4.09 de 5) 


Nível Intermediário

Masm32+RadASM

Capítulo III: Registradores do Microprocessador

Escrito por: ^A|An M0r3N0^
Conselheiro: RedH@wk
Tradução: ~Uglinho~
O presente texto foi escrito para fins educacionais e de pesquisa e é de livre distribuição contanto que se preserve o conteúdo e os direitos do autor.

Registradores do Microprocessador

Nosso processador precisa de registradores para armazenar dados que podem ser utilizados livremente. Entre os principais registradores temos:

Registradores de propósito geral

São 4 registradores - EAX, EBX, ECX, EDX - que são empregados para uso geral. Subdividem-se em:

EAX, EBX, ECX, EDX (32 bits)
AX, BX, CX, DX (16 bits)
AH, BH, CH, DH (8 bits, H = High) AL, BL, CL, DL (8 bits, L = Low)

Exemplo:

EAX = 12345678
 AX =     5678
 AH =     56
 AL =       78

O processador 80386 permite o uso destes registradores - EAX, EBX, ECX, EDX - que são de 32 bits.

Registradores de uso geralDescrição
EAX (Acumulador) É utilizado para operações aritméticas (soma, subtração, divisão e multiplicação). Algumas funções, depois de serem utilizadas, devolvem um valor para EAX.
EBX (Base) É utilizado para direcionar o acesso a dados situados na memória. Também pode ser utilizado para operações aritméticas.
ECX (Contador) É utilizado como contador por algumas instruções. Também é utilizado para operações aritméticas.
EDX (Dados) Algumas operações de entrada/saída requerem seu uso e as operações de multiplicação e divisão com algarismos grandes supõem que EDX e EAX trabalhem juntos. Pode usar os registradores para soma e subtração de valores de 8, 16, 32 bits.
.
Registradores de ÍndiceDescrição
ESI Este registrador de índice de 16 bits é requerido por algumas operações com cadeias (de caracteres).
EDI Este registrador de índice de destino também é requerido por algumas operações com cadeias de caracteres.
.
Registradores de Bandeiras (Flags)Descrição
São usados para registrar a informação de estado e de controle das operações do microprocessador. São 9: CF, OF, ZF, SF, PF, AF, DF, IF, TF.

Instruções do microprocessador

As instruções são sequências de bits (uns e zeros). Indicam qual operação deve ser feita e com que dados operação deve ser realizada. Por enquanto veremos 11 instruções:

MOV (mover) DESTINO FONTE

Esta instrução MOV significa mover e se encarrega de passar o conteúdo do operando Fonte para o do Destino. Na programação devemos respeitar as seguintes regras: Destino - Podem ser variáveis e registradores de 8, 16 e 32 bits; Fonte - Podem ser variáveis, registros do Windows e valores inteiros.

ADD (soma) DESTINO FONTE

A instrução ADD significa Somar. Soma o conteúdo dos dois operandos e o resultado é repassado para o operando Destino.

Destino - Podem ser variáveis e registradores de 8, 16 e 32 bits. Fonte - Podem ser variáveis, registros do Windows e valores inteiros.

SUB (subtração) DESTINO FONTE

A instrução SUB significa Subtrair. Subtrai o conteúdo do operando Fonte do Destino e o resultado é armazenado no operando Destino.

Destino - Podem ser variáveis e registradores de 8, 16 e 32 bits. Fonte - Podem ser variáveis, registros do Windows e valores inteiros.

INC (incrementa 1) DESTINO DEC (decrementa 1) DESTINO

Estas instruções incrementam e decrementam respectivamente o valor contido no operando Destino. Destino - Podem ser variáveis e registradores de 8, 16 e 32 bits.

PUSH (guarda) FONTE

PUSH se encarrega de guardar o conteúdo do operando Fonte na Pilha. Fonte - Podem ser variáveis, valores inteiros e registradores de 16 e 32 bits.

POP (recupera) DESTINO

Ao contrário de PUSH, esta instrução recupera o conteúdo guardado na pilha. Destino - Podem ser variáveis e registradores de 16 e 32 bits.

Quando guardamos vários valores com a instrução PUSH e quiseremos recuperar estes valores, utilizamos a instrução POP respeitando a seguinte regra:

"O último valor guardado será o primeiro a ser recuperado".


Para instruções lógicas: Utilize a calculadora do Windows (no modo científico) para passar para os sistemas decimal, hexadecimal e binário os valores indicados.

AND DESTINO FONTE

Realiza a operação lógica AND entre os operandos Fonte e Destino, bit a bit, e o resultado é repassado para o operando Destino.

TABELA VERDADE AND
ABResultado
000
010
100
111

Exemplo:

1110  (14 decimal ou E hexadecimal)
1101  (13 decimal ou D hexadecimal)
----
1100  (12 decimal ou C hexadecimal)
OR DESTINO FONTE

Realiza a operação lógica OR entre os operandos, bit a bit, e o resultado é repassado para o operando Destino.

TABELA VERDADE OR
ABResultado
000
011
101
111

Exemplo:

1110  (14 decimal ou E hexadecimal)
1101  (13 decimal ou D hexadecimal)
----
1111  (15 decimal ou F hexadecimal)
NOT DESTINO

A instrução NOT inverte os bit no operando Destino.

TABELA VERDADE NOT
AResultado
01
10

Exemplo:

1101  (13 decimal ou D hexadecimal)
----
0010  (2 decimal ou 2 hexadecimal)
XOR DESTINO FONTE

Realiza a operação lógica XOR entre os operandos, bit a bit, e o resultado é repassado para o operando Destino.

TABELA VERDADE XOR
ABResultado
000
011
101
110

Exemplo:

1110  (14 decimal ou E hexadecimal)
1101  (13 decimal ou D hexadecimal)
----
0011  (3 decimal ou 3 hexadecimal)

Todas as operações lógicas que vimos têm a seguinte regra: Fonte - Podem ser variáveis, valores e registradores de 16 e 32 bits; Destino - Podem ser variáveis e registradores de 16 e 32 bits.


Exercícios com instruções

Abrimos o arquivo prog002a com a nossa IDE RadAsm, onde encontramos o seguinte:

vovo Faça o download de prog002a.zip.

No arquivo .INC está declarada a variável Valor_1 do tipo DD.

prog002a: ;##################[Operações Aritméticas]################ MOV EAX,444 ; EAX = 444 ADD EAX,333 ; EAX = 444 + 333 = 777 MOV Valor_1,EAX ; Movemos o Resultado para a ; variável Valor_1 = EAX = 777 MOV EBX,15Dh ; EBX = 15Dh MOV EAX,20Ch ; EAX = 20Ch ADD EAX,EBX ; EAX = 20Ch + EBX = 15Dh = 369h PUSH EBX ; Guardamos o conteúdo do Registrador EBX = 15Dh ; na Pilha. DEC EAX ; Decrementamos 1 em EAX = 369h - 1 = 368h INC EBX ; Incrementamos 1 em EBX = 15Dh + 1 = 15Eh SUB EAX, EBX ; Subtraimos EAX = 368h - EBX = 15Eh = 20Ah POP EBX ; Recuperamos o conteúdo da Pilha para o registrador EBX SUB EBX,10 ; Subtraimos EBX = 15Dh - 10 = 153

Quando queremos declarar números em Hexadecimal, devemos escrever o caractere h no final do valor. Se não houver nenhum caractere no final, significa que é decimal.

;##################[Operações Lógicas]################ MOV EAX,12 ; 12 = 1100b MOV EBX,11 ; 11 = 1011b AND EAX,5 ; EAX=12 (1100b) And 5(0101b) = 4 (0100b) OR EAX,EBX ; EAX= 4(0100b) OR EBX 11(1011b) = F(1111b) OR EBX,1101b ; EBX = 11(1011b) OR 13(1101b) = F(1111b) XOR EAX, EBX ; EAX = F(1111b) XOR EBX = F(1111b) = 00000 PUSH -2 ; Guardamos na Pilha o valor -2 POP EBX ; Recuperamos o valor guardado na pilha no registrador EBX NOT EBX ; NOT EBX = -2 = 1

Quando quisermos declarar números binários, devemos escrever o caractere b no final do valor inteiro. Nas operações lógicas, se quisermos comprovar os resultados, podemos verificar a tabela verdade correspondente a cada operação.

O programa acima é só um exemplo de como usar apropriadamente as instruções. Agora vamos dar sentido ao nosso programinha.

Temos 5 valores inteiros:

1 - 1Ah 
2 - 500 
3 - 1C2h 
4 - 13h 
5 - 200

Faremos um programa que faça a seguinte operação:

  • 1Ah + 500 = X
  • Do resultado X subtraímos 1C2h: X – 1C2h = Y
  • Guardamos o resultado Y na Pilha ou numa variável e depois somaremos as quantidades que até agora não utilizamos, desta maneira:
    • 13h + 200 = Z
  • Recuperamos o resultado Y e dele subtraímos a quantidade do resultado Z. O resultado final deve ser armazenado no registrador EAX.

Solução Nº1 (prog002b)

No arquivo .inc declaramos a variável Y tipo DD.

prog002b: mov eax,1Ah ; EAX = 1AH add eax,500 ; EAX = 1Ah + 500 = 526 sub eax,1C2h ; EAX = 526 – 1C2 = 76 mov Y, eax ; Y (variável) = EAX = 76 mov eax, 13h ; EAX = 13H add eax,200 ; EAX = 13H + 200 = 219 sub eax ,Y ; EAX = 219 - Y (76) = 143

O resultado final é EAX = 143.

vovo Faça o download de prog002b.zip.

Solução Nº2 (prog002c)

Todos os valores estão declarados no arquivo .inc do nosso programa onde:

Valor_1 DD 1Ah Valor_2 DD 500 Valor_3 DD 1C2h Valor_4 DD 13h Valor_5 DD 200 prog002c: mov eax,Valor_1 ; EAX = 1Ah add eax,Valor_2 ; EAX = 1Ah + 500 = 526 sub eax,Valor_3 ; EAX = 526 – 1C2 = 76 push eax ; Guardamos na Pilha o conteúdo de EAX = 76 mov eax,Valor_4 ; EAX = 13H add eax,Valor_5 ; EAX = 13H + 200 = 219 pop ebx ; Recuperamos o conteúdo de EAX em EBX = 76 sub eax,ebx ; EAX = 219 - Y (76) = 143

Há muitas soluções, não só estas duas. Se vocês desejarem aprender mais, devem desenvolver suas próprias soluções.

vovo Faça o download de prog002c.zip.


Mostrando resultados

No nosso código anterior não é mostrado o resultado da operação aritmética. Para isto devemos conhecer as seguintes funções de conversão da masm32.lib:

atodw,addr Numero_decimal

Esta função converte cadeias de texto (quantidades decimais) para seu valor inteiro e a quantidade convertida será devolvida para EAX. Exemplo:

.data Numero_decimal db "10",0 .code Invoke atodw,addr Numero_decimal mov ebx, eax ;EAX contém o valor inteiro 10 ou Ah
htodw,addr Numero_Hexadecimal

Esta função é semelhante à atodw, mas trabalha com quantidades hexadecimais e as converte para o seu valor inteiro. A quantidade convertida será devolvida para EAX.

dwtoa,Quantidade,addr Numero_Convertido_decimal

Esta função converte valores inteiros em cadeias de texto decimal. Seria o contrário da função atodw.

Quantidade - Neste parâmetro se pode utilizar variáveis, valores inteiros e registros do windows. Exemplo:

Caso 1 - valor inteiro: Invoke dwtoa,12, addr Numero_Convertido_decimal Caso 2 - Variáveis tipo DD: Invoke dwtoa, Valor_1, addr Numero_Convertido_decimal Caso 3 - Registros do Windows: Invoke dwtoa, EAX, addr Numero_Convertido_decimal
dw2hex,Quantidade,addr Numero_Convertido_Hex

Esta função possui os mesmos parâmetros da função dwtoa, com a diferença de que o resultado é uma quantidade de texto hexadecimal. É o contrário da função htodw.


Nos exemplos a seguir utilizaremos todas as funções mencionadas. Preste muita atenção em cada detalhe.

1 - No exercício seguinte mostraremos o resultado em decimal e hexadecimal em uma mensagem:

Vídeo 1
prog002d.exe

vovo Para assistir ao vídeo, faça o download de prog002d.exe.

2 - Faremos um programa que soma cadeias de texto com quantidades decimal e hexadecimal e que, no final, deve mostrar o resultado:

Vídeo 2
prog003.exe

vovo Para assistir ao vídeo, faça o download de prog003.exe.

No exemplo prog003.exe observamos que tínhamos quantidades em decimal e hexadecimal (cadeias de texto) e depois, para somar estas quantidades, as convertemos para valores inteiros com as funções atodw e htodw para que pudéssemos operar com instruções do processador como a de somar (ADD) e mover (MOV). Depois, para mostrar o resultado, devemos converter os valores inteiros para cadeias de texto com as funções dwtoa e dw2hex respectivamente:

Esquema do trabalho:

Esquema 1

Vejamos outro exemplo de conversão. Lembre-se de estar sempre atento a cada detalhe do vídeo:

Vídeo 3
prog003a.exe

vovo Para assistir ao vídeo, faça o download de prog003a.exe.

Foi trabalhado diretamente com valores inteiros declarados em nosso arquivo .inc, cujas quantidades foram somadas. Depois, para mostrar o resultado, convertemos para cadeias de texto dwtoa e dw2hex, respectivamente.

Esquema de trabalho:

Esquema 2

Assim levamos em conta a conversão de valores inteiros para cadeias e vice-versa.

Nota: Nunca podemos mostrar valores inteiros. Para fazer isto devemos converter os valores para cadeias de texto.


Criando suas próprias funções

1 - Agora criaremos uma função que mostre uma mensagem. Esta função terá um parâmetro para indicar o endereço da etiqueta da mensagem. Dentro da função que vamos criar se encontra a API MessageBox, que será reponsável por mostrar a mensagem.

Vídeo 4
prog004.exe

vovo Para assistir ao vídeo, faça o download de prog004.exe.

Como observamos no vídeo, primeiro declaramos a função que vamos utilizar:

Funcion PROC MsgT:DWORD invoke MessageBox,NULL,MsgT,addr MsgTitulo, MB_OK + MB_ICONINFORMATION RET Funcion endp

PROC - Esta diretiva serve para definir um procedimento ou chamado que se irá utilizar e sua sintaxe é assim:

Nome_da_Funcao PROC  Argumento/s (se tiver um) 
RET 
Nome_da_Funcao endp

Se nossa função precisar de um parâmetro, sua sintaxe seria assim:

Nome_da_Funcao PROC  Parametro01: Tipo de variável 
RET 
Nome_da_Funcao endp

Se nossa função precisar de mais de um parâmetro, é necessário separar com "," (virgulas) cada parâmetro, desta maneira:

Nome_da_Funcao PROC  Prmtr01: Tipo de variável, Prmtr02: Tipo de variável, etc.
RET 
Nome_da_Funcao endp

Tipo de variável - Aqui declaramos o comprimento em bytes que se precisa, ou seja: DWORD, WORD, BYTE. Em geral sempre se declara a variável usando o maior comprimento (tamanho) como DWORD.

Nome_da_Funcao - Aqui escrevemos nossa etiqueta para o nome da função. Lembre-se de que esta etiqueta não deve se repetir e que a etiqueta dos parâmetros não deve ser declarada em outra parte do código.

RET (retorno) Nº Bytes

Com esta instrução retornamos do procedimento que chamamos. Também a utilizamos para separar nossos códigos, como no primeiro RET que vem depois da função ExitProcess. O operando Nº Bytes é opcional. Especifica quantos bytes devem retornar.

Outro ponto importante é que, se utilizarmos algumas das variáveis que declaramos nos parâmetros do procedimento da função, como por exemplo MsgT, já não é necessário utilizar addr ou offset. Um exemplo é a variável que foi utilizada no 3º parâmetro da Api MessageBox:

invoke MessageBox,NULL,MsgT,addr MsgTitulo, \ MB_OK + MB_ICONINFORMATION

Já criamos nossa função. Se quisermos utilizá-la com a diretiva invoke, ficaria assim - como fizemos no vídeo:

invoke Funcion,addr MsgTexto

É necessário declarar os protótipos com a diretiva PROTO.

PROTO - Serve para definir os protótipos das funções para que possam ser usadas com invoke. Também informa ao MASM o número de argumentos e o tipo de variável que deve ser usada no momento de se chamar uma função. Sua sintaxe é:

Nome_da_Funcao PROTO Argumento/s (se tiver um)

PROTO é semelhante à diretiva PROC porque ambas trabalham em conjunto. A diferença está na declaração dos tipos de variáveis. O número de variáveis que declaramos depende dos parâmetros da função, por exemplo:

invoke Funcion,addr MsgTexto

É necessário declarar os protótipos com a diretiva PROTO.

PROTO - Serve para definir os protótipos das funções para que possam ser usadas com invoke. Também informa ao MASM o número de argumentos e o tipo de variável que deve ser usada no momento de se chamar uma função. Sua sintaxe é:

Nome_da_Funcao PROTO Argumento/s (se tiver um)

PROTO é semelhante à diretiva PROC porque ambas trabalham em conjunto. A diferença está na declaração dos tipos de variáveis. O número de variáveis que declaramos depende dos parâmetros da função, por exemplo:

invoke Funcion,addr MsgTexto

só contém um parâmetro e o definimos desta maneira:

Funcion PROTO :DWORD

Se nossa função tiver mais de um parâmetro, declara-se as variáveis separando-as com "," (virgulas). Por exemplo, a função MessageBoxA, que está no arquivo user32.inc, quando utilizada precisa de 4 parâmetros:

MessageBoxA PROTO :DWORD,:DWORD,:DWORD,:DWORD

Nota - Não se esqueça de que se deve respeitar as maiúsculas e minúsculas quando nos referirmos a qualquer variável ou um nome de função porque, se não o fizermos, na hora de compilar o masm32 nos devolverá erros.


2 - Criaremos uma função que subtraia 2 quantidades e, depois de regressar da função, o resultado deve ser devolvido ao registro EAX. No final deve mostrar o resultado em decimal.

Vídeo 5
prog004a.exe

vovo Para assistir ao vídeo, faça o download de prog004a.exe.

Dentro da nossa função Resta, colocamos 2 instruções para poder subtrair quantidades. Já sabemos como estas instruções são utilizadas porque tudo já foi bem explicado. Depois, o resultado é armazenado em EAX e, ao retornar da função, convertemos o valor inteiro em cadeias de texto (recordar que a função de conversão está na biblioteca masm32.lib) para poder mostrar o resultado com a API MessageBox.

Nota - Na função criada pode-se usar valores como também variáveis e registradores de 8, 16, 32 bits por que tudo isto se inclui em DWORD.

Exercícios

  1. Temos 3 valores - 800, 400, 100 (decimais) - em cadeias de texto e queremos um programa que faça a seguinte operação:
    800 – 450 = X
    e deve-se substrair 100 do resultado X para obter Y. Este resultado deve ser mostrado.
  2. Criar um programa que some 5 quantidades e a soma destas quantidades serão reduzidas em 225 decimal. As 5 quantidades podem ser qualquer valor inteiro, desde que sejam em decimal ou hexadecimal. Se quiser mostrar o resultado, faça-o.
  3. Criar uma função que tenha 2 parâmetros para que mostre uma mensagem portanto:
    O primeiro parâmetro - Aqui se colocará o endereço da etiqueta da Mensagem que se irá mostrar.
    O segundo parâmetro - Aqui se colocará o endereço da etiqueta do título da mensagem.

Vocabulário

Pilha ou stack - A pilha é uma área de memória que pode ser utilizada para o armazenamento temporário de dados. Só 2 instruções trabalham com a pilha: são o PUSH (guarda) e o POP (recupera).

Lembrando

Não esquecer de perguntar na lista MASM32-RadASM. As soluções destes exercícios serão enviados para a lista dentro de uma semana. Vocês também podem enviar suas prórias soluções.

Se tiverem dúvidas, sugestões ou outros, faça-as na lista de discussão.

O autor pode ser contactado

eMail: O endereço de e-mail address está sendo protegido de spambots. Você precisa ativar o JavaScript enabled para vê-lo. ou O endereço de e-mail address está sendo protegido de spambots. Você precisa ativar o JavaScript enabled para vê-lo.

Lista de discussão MASM32-RadASM

http://groups.google.es/group/MASM32-RadASM

www


Julio-2006
Copyright(c) 2005-2006 RVLCN



Recado da vó vovo

Aqui está o código fonte dos exercícios deste tutorial:

capital mfx гриль этоотзывы полигонповышение эффективностимощный игровой ноутбук купитьзаказать набор кистей для макияжалобановский александр

Informações adicionais