15/10/2014

Começando em Assembly: Movendo e somando         valores


Vamos mover alguns valores de variáveis para registradores, e fazer uma soma :)



Aqui você pode ver que depois das instruções das linhas 18, 19 e 22 serem executadas. Ax e bx ficam com o valor da nossa variável (que é 4F(numero em hexadecimal)).



E agora, depois das instruções das linhas 23 e 24 serem executadas. É somado +5 em ax e esse valor é              movido para bx. Assim ax e bx ficam valendo 54h.




Código disponível para cópia:
code segment
code segment
mov dl,30h ; move o valor correspondente ao caracter 0 na tabela ASCII para DL

incrementa: ; rotina que imprime os números e soma 1
mov ah,02h ; estabelece que o cursor escreverá o caracter na primeira posição da tela
int 21h ; imprime o número

mov ax,3h ; com isso, a instrução int 10h limpa a tela
int 10h ; instrução relacionada a serviços de vídeo, neste caso limpa a tela

cmp dl,39h ; compara o valor de dl com 39 (caracter 9 na tabela ASCII)
je zera ; se for igual a 39, pula pra rotina “zera”, onde o valor de DL voltará a 30h
inc dl ; caso contrário, aumenta em 1 o valor de DL
jmp incrementa ; volta para a rotina “incrementa” e repete o processo

zera:
mov dl,30h ; valor de DL volta a ser 30h (0)
jmp incrementa ; pula para a rotina “incrementa”, onde será aumentado o valor

ends ;fim do segmento de código




Exemplo em Assembly: Contador de 0 a 9

Este é um programa que incrementa números de 0 a 9, retornando para 0 ao final e reiniciando a contagem:



Como não vamos usar nenhuma variável nem a pilha, não precisamos declará-las.
Vamos direto ao code segment.




Quando você emular o código no EMU8086 ele pode ficar muito rápido. Você pode mudar isso fazendo um delay, usando a barra indicada abaixo.




Essa é a tabela ASCII:

Os caracteres(char) são representados por números decimais ou hexadecimais. Como demonstrado abaixo, os caracteres 0 até 9 são equivalentes ao números, em hexadecimal, de 30 até 39. 






Código disponível para cópia:
code segment
code segment
mov dl,30h ; move o valor correspondente ao caracter 0 na tabela ASCII para DL

incrementa: ; rotina que imprime os números e soma 1
mov ah,02h ; estabelece que o cursor escreverá o caracter na primeira posição da tela
int 21h ; imprime o número

mov ax,3h ; com isso, a instrução int 10h limpa a tela
int 10h ; instrução relacionada a serviços de vídeo, neste caso limpa a tela

cmp dl,39h ; compara o valor de dl com 39 (caracter 9 na tabela ASCII)
je zera ; se for igual a 39, pula pra rotina “zera”, onde o valor de DL voltará a 30h
inc dl ; caso contrário, aumenta em 1 o valor de DL
jmp incrementa ; volta para a rotina “incrementa” e repete o processo

zera:
mov dl,30h ; valor de DL volta a ser 30h (0)
jmp incrementa ; pula para a rotina “incrementa”, onde será aumentado o valor

ends ;fim do segmento de código

08/10/2014

Exemplo em Assembly: Escrevendo números em         binário

Hoje vamos fazer um programa para escrever números em binário. Ele irá escrever os números em binário    até 42.

Explicação da instrução ROL




 
   INSTRUÇÕES USADAS NO SOFTWARE:
MOV: atribuição de valor
ROL: rotaciona o bit mais a esquerda para esquerda.(Vê la na imagem que é de boa)
JMP: jumpar, pular para
CMP: comparação. Se CL for igual a X, por exemplo
INC: Incrementa +1 no registrador. Exemplo: INC DH, incrementa +1 no registrador DH
JE: jump if equals/pule se for igual
JC: jump if carry. Pula se houver carry(1)
JNC: jump if no carry. Pula se não houver carry(0)
JMP: pulo incondicional.  



Código disponível para cópia:
code segment
start:
;comeca
MOV DH,00000000B ;comeca com o numero 0

IMPRIME:
 MOV CL,0 ;deixa o CL com 0

ROTACIONA: 
 ROL DH, 1 ;joga um numero(sempre o primeiro) para a esquerda, como demonstrado na imagem1 acima 
 JC UM     ;se o numero jogado p/ esquerda for 1, pula para sub-rotina UM:
 JNC ZERO  ;se for 0, pula para sub-rotina ZERO:

VERIFICA:         ;verifica quantos numeros ja foram jogados para esquerda
 INC CL        ;incrementa 1 um CL
 CMP CL,8      ;ate que CL seja igual a 8
 JE PROXIMO    ;quando CL for 8, pula para a sub-rotina PROXIMO:
 JMP ROTACIONA ;enquanto nao for, repete a sub-rotina ROTACIONA:

UM:             ;imprime o numero 1
 MOV AH,2      ;rotina para imprimir um caracter
 MOV DL,"1"    ;manda uma string com o numero '1' para o video
 INT 21H       ;chama o servico de video p/ efetuar a impressao
 JMP VERIFICA  ;pula para a sub-rotina VERIFICA:

ZERO:            ;imprime o numero 0
 MOV AH,2      ;rotina para imprimir um caracter 
 MOV DL,"0"    ;manda uma string com o numero '0' para o video
 INT 21H       ;chama o servico de video p/ efetuar a impressao
 JMP VERIFICA  ;pula para a sub-rotina VERIFICA:

PROXIMO:  ;essa sub-rotina pula uma linha para imprimir o proximo numero e verifica se todos os numeros ja foram escritos
 MOV AH,2 
 MOV DL,13
 INT 21H
 MOV AH,2
 MOV DL,10
 INT 21H 

 INC DH     ;incrementa 1 em DH
 CMP DH,43  ;ate DH ser 42
 JE FIM     ;se dh for 42. Pula para sub-rotina FIM: e encerra o programa
 JMP IMPRIME;se for diferente(nesse caso, menor que 42). Pula para IMPRIME:

FIM: 
ends
end start ;fim


ou faça download do projeto. (Só abrir com o EMU8086)

Começando em Assembly: Instalação e básico o do      EMU8086.


Antes de tudo você vai precisa baixar o EMU8086, aconselho você usar a versão mais completa. Mas você pode usar a versão básica.

Iremos usar o template de arquivos .EXE



O template vai vir como o da imagem abaixo. Você pode deletar o conteúdo marcado abaixo



O botão emulate faz a simulação de compilação, ou seja, ele compila as paradas.



Como o EMU8086 trabalha com números em hexadecimal ele já tem um conversor integrado.



Ao emular nosso programa, temos dois botões principais. O Sigle Step, que faz o programa executar uma      instrução de cada vez. E o Run, que executa o programa normalmente.



O EMU8086 disponibiliza essas opções ao emular nosso programa.


Temos o conteúdo dos registradores, em azul. A pilha, cinza. As variáveis, verde. As flags, em vermelho...



 ...O display, e nosso código fonte.



Fiz um código simples para demonstrar como os registradores funcionam. O código é o seguinte:
mov ax, minhaVar    ; move para ax o conteúdo da variável "minhaVar", que é o número 6.
add ax, 1                   ; adiciona 1 no registrador ax. Ou seja, o ax agora vale 7.
mov bx, minhaVar   ; move para bx o conteúdo da variável "minhaVar"


Aqui podemos ver que o conteúdo da variável é movido para ax


E aqui vemos que é adicionado 1 em ax. Agora ax vale 7. Também podemos observar que a variável é          movida para bx, e assim, bx agora vale 6.



Esse é o EMU8086, espero que vocês tenha entendido como ele funciona. Qualquer dúvida, deixe nos comentários ;)

Até a próxima!