Tutorial de asm parte II!
Death Knights Issue 4
by Hunter^Heads
bom vamos, falar sobre programacao ?
kx.. tipo primeiramente bora aprender a mexer com o debug ...
como criar um programa em debug:
- Desenvolvimento do algoritmo, estagio em que o problema a ser solucionado B estabelecido e a melhor solucao e proposta, criacao de diagramas esquematicos relativos E melhor solucao proposta.
- Codificacao do algoritmo, o que consiste em escrever o programa em alguma linguagem de programacao; linguagem assembly neste caso espec!fico, tomando como base a solucao proposta no passo anterior.
- A transformacao para a linguagem de m quina, ou seja, a criacao do programa objeto, escrito como uma sequencia de zeros e uns que podem ser interpretados pelo processador.
- O ultimo estagio e a eliminacao de erros detectados no programa na fase de teste. A correcao normalmente requer a repeticao de todos os passos, com observacao atenta.
bom os principais passos foram tomados.. agora bora brincar de registrador da merda da sua maq.
Para o proposito didatico, vamos focar registradores de 16 bits. A CPU possui 4 registradores internos, cada um de 16 bits. Sao eles AX, BX, CX e DX. Sao registradores de uso geral e tambem podem ser usados como registradores de 8 bits. Para tanto devemos referencia-los como, por exemplo, AH e AL, que sao, respectivamente, o byte high e o low do registrador AX. Esta nomenclatura tambem se aplica para os registradores BX,M CX e DX.
- ES Registrador de Segmento Extra
- SS Registrador de Segmento de Pilha
- CS Registrador de Segmento de Codigo
- BP Registrador Apontador da Base
- SI Registrador de indice Fonte
- DI Registrador de indice Destino
- SP Registrador Apontador de Pilha
- IP Registrador Apontador da Prixima Instrucao
- F Registrador de Flag
- AX Registrador Acumulador
- BX Registrador Base
- CX Registrador Contador
- DX Registrador de Dados
- DS Registrador de Segmento de Dados
Para a criacao de um programa em assembler existem 2 opGdes: usar o TASM -M
Turbo Assembler da Borland, ou o DEBUGGER. Nesta primeira vamos usar o debug, uma vez que podemos encontr -lo em qualquer PC com o MS-DOS. Debug pode apenas criar arquivos com a extensao .COM, e por causa das caracteristicas deste tipo de programa, eles nao podem exceder os 64 Kb, e tambem devem iniciar no endereco de memoria 0100H dentro do segmento especifico. E importante observar isso, pois deste modo os programas .COM nao sao relocaveis.
principais comandos do debug
- A Montar instrucoes simbolicas em codigo de maquina
- D Mostrar o conteudo de uma area da memoria
- E Entrar dados na memoria, iniciando num endereco especifico
- G Rodar um programa executavel na memoria
- N Dar nome a um programa
- P Proceder, ou executar um conjunto de instrucoes relacionadas
- Q Sair do programa debug -> este vc jah sabia? eaheha
- R Mostrar o conteudo de um ou mais registradores
- T Executar passo a passo as instrucoes
- U Desmontar o codigo de m quina em instrucoes simbolicas
- W Gravar um programa em disco
E possivel visualizar os valores dos registradores internos da CPU usando o programa Debug. Debug e um programa que faz parte do pacote do DOS, e pode ser encontrado normalmente no diretorio C:\DOS. Para inicia-lo, basta digitar Debug na linha de comando:
M
C:#:)>Debug [Enter]
Voce notara entao a presenca de um hifen no canto inferior esquerdo da tela.Nao se espante, este e o prompt do programa. Para visualizar o conteudo dosM registradores, experimente:buuuuh
-r[Enter]
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D62 ES=0D62 SS=0D62 CS=0D62 IP=0100 NV UP EI PL NZ NA PO NC
0D62:0100 2E CS:
0D62:0101 803ED3DF00 CMP BYTE PTR [DFD3],00
CS:DFD3=03
E mostrado o conteudo de todos os registradores internos da CPU; um modo alternativo para visualizar um unico registrador e usar o camando "r" seguido do paremetro que faz referencia ao nome do registrador:
-rbx
BX 0000
:MC
Esta instrucao mostrar o conteudo do registrador BX e mudar o indicador do Debug de "-" para ":"
Quando o prompt assim se tornar, significa que e poss!vel, embora nao obrigatoria, a mudanca do valor contido no registrador, bastando digitar o novo valor e pressionar [Enter]. Se voce simplesmente pressionar [Enter] o valor antigo ira se manter.
Estrutura Assembly
Nas linhas do codigo em Linguagem Assembly e duas partes: a primeira e o nome da instrucao a ser executada; a segunda, os parimetros do comando. Por exemplo:
add ah bh
Aqui "add" B o comando a ser executado, neste caso uma adicao, e "ah" bem como "bh" sao os parimetros.
Por exemplo:
mov al, 25
No exemplo acima, estamos usando a instrucao mov, que significa mover o valor 25 para o registrador al.
M
O nome das instrucoes nesta linguagem e constitu!do de 2, 3 ou 4 letras.
Estas instrucoes sao chamadas codigos de operacao,representando a funcao que o processador executar.
as vezes instrucoes aparecem assim:
add al,[170]
Os colchetes no segundo parimetro indica-nos que vamos trabalhar com o conteudo da celula de memoria de numero 170, ou seja, com o valor contido no endereco 170 da memoria e nao com o valor 170, isto e conhecido como enderecamento direto.
O primeiro passo e iniciar o Debug, o que jah vimos como fazer anteriormente.
Para montar um programa no Debug, e usado o comando "a" (assemble); quando usamos este comando, podemos especificar um endereco inicial para o nosso programa como o parimetro, mas e opcional. No caso de omissao, o endereco inicial e o especificado pelos registradores CS:IP, geralmente 0100h, o local em que programas com extensFo .COM devem iniciar. E ser este o local que usaremos, uma vez que o Debug so pode criar este tipo de programa.
Embora neste momento nao seja necessario darmos um parimetro ao comando "a", isso e recomendavel para evitar problemas, logo:
a 100[enter]
mov ax,0002[enter]
mov bx,0004[enter]
add ax,bx[enter]
nopA[enter][enter]
O que o programa faz? Move o valor 0002 para o registrador ax, move o valor 0004 para o registrador bx, adiciona o conteudo dos registradores ax e bx, guardando o resultado em ax e finalmente a instrucao nop (nenhuma operacao) finaliza o programa.
No programa debug, a tela se parecer com:
C:\>debug
-a 100
0D62:0100 mov ax,0002
0D62:0103 mov bx,0004
0D62:0106 add ax,bx
0D62:0108 nop
0D62:0109
Entramos com o comando "t" para executar passo a passo as instrucoes:
-t
AX=0002 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D62 ES=0D62 SS=0D62 CS=0D62 IP=0103 NV UP EI PL NZ NA PO NC
0D62:0103 BB0400 MOV BX,0004
Vemos o valor 0002 no registrador AX. Teclamos "t" para executar a segunda instrucao:
-t
AX=0002 BX=0004 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D62 ES=0D62 SS=0D62 CS=0D62 IP=0106 NV UP EI PL NZ NA PO NC
0D62:0106 01D8 ADD AX,BX
Teclando "t" novamente para ver o resultado da instrucao add:
-t
AX=0006 BX=0004 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0D62 ES=0D62 SS=0D62 CS=0D62 IP=0108 NV UP EI PL NZ NA PE NC
0D62:0108 90 NOP
A possibilidade dos registradores conterem valores diferentes existe, mas AX e BX devem conter os mesmos valores acima descritos.
Para sair do Debug usamos o comando "q" (quit).
carregando / armazenando os bixinhos
Nao seria pratico ter que digitar o programa cada vez que iniciassemos o Debug. Ao inves disso, podemos armazen -lo no disco. so que o mais interessante nisso e que um simples comando de salvar cria um arquivo com a extensao .COM, ou seja, executavel sem precisarmos efetuar os processos de montagem e ligacao, como veremos posteriormente com o TASM.
Eis os passos para salvar um programa que ja esteja na memoria:
- Obter o tamnho do programa subtraindo o endereco final do endereco inicial, naturalmente que no sistema hexadecimal.
- Dar um nome ao programa.
- Colocar o tamanho do programa no registrador CX.
- Mandar o debug gravar o programa em disco.
Usando como exemplo o seguinte programa, vamos clarear a ideia de como realizar os passos acima descritos:
0C1B:0100 mov ax,0002
0C1B:0103 mov bx,0004
0C1B:0106 add ax,bx
0C1B:0108 int 20
0C1B:010A
Para obter o tamanho de um programa, o comando "h" e usado, ja que ele nos mostra a adicao e subtracao de dois numeros em hexadecimal. Para obter o tamanho do programa em questao, damos como parimetro o valor do endereco final do nosso programa (10A), e o endereGo inicial (100). O primeiro resultado mostra-nos a soma dos enderecos, o segundo, a subtracao.
-h 10a 100
020a 000a
O comando "n" permite-nos nomear o programa.
-n test.com
O comando "rcx" permite-nos mudar o conteudo do registrador CX para o valor obtido como tamanho do arquivo com o comando "h", neste caso 000a.
-rcx
CX 0000
:000a
Finalmente, o comando "w" grava nosso programa no disco, indicando quantos bytes gravou.
-w
Writing 000A bytes
Para ja salvar um arquivo quando carreg -lo, 2 passos sao necessarios:
Dar o nome do arquivo a ser carregado.
Carrega-lo usando o comando "l" (load).
Para obter o resultado correto destes passos, e necessario que o programa acima ja esteja criado.
Dentro do Debug, escrevemos o seguinte:
-n test.com
-l
-u 100 109
0C3D:0100 B80200 MOV AX,0002
0C3D:0103 BB0400 MOV BX,0004
0C3D:0106 01D8 ADD AX,BX
0C3D:0108 CD20 INT 20
O ultimo comando "u" e usado para verificar que o programa foi carregado na memoria. O que ele faz e desmontar o codigo e mostra-lo em assembly. Os parimetros indicam ao Debug os enderecos inicial e final a serem desmontados.
O Debug sempre carrega os programas na memoria no endereco 100h, conforme ja comentamos.
Hunter^Heads HunterH@deathknights.com
`'`'`'`'`'`' `'`'`'`'`'`'`'`'`'`'`'`'