Baixe o app para aproveitar ainda mais
Prévia do material em texto
1 Arquitetura e Debug Autor PROF. C. P. BIFONI Ricardo Paulo Brzozowski 2 1 -LINGUAGEM ASSEMBLY 1.1 BIBLIOGRAFIA RECOMENDADA 3 1.2 ARQUITETURA DO MICROPROCESSADOR DE 16 BITS 4 1.2.1 MICROPROCESSADOR 8088 4 1.2.1.1 BARRAMENTOS 4 1.2.1.2 DIAGRAMA DA CPU DO 8088 5 1.2.2 REGISTRADORES 6 1.2.2.1 REGISTRADORES GERAIS 6 1.2.2.1.1 DE DADOS 6 1.2.2.1.2 INDICES E PONTEIROS 6 1.2.2.1.3 PILHA 7 1.2.2.2 REGISTRADORES DE SEGMENTOS 7 1.2.2.3 REGISTRADORES DE CONTROLE 9 1.3 EXERCÍCIOS DE FIXAÇÃO 12 2 -NOÇÕES PRILIMINARES (CONTINUAÇÃO) 2.1 BYTE - WORD - DWORD 15 2.2 ENDEREÇO LÓGICO - ENDEREÇO FÍSICO - EA 15 2.3 ARMAZENAMENTO DE WORD NA MEMÓRIA 15 2.4 ENDEREÇAMENTO À MEMÓRIA 16 2.4.1 POR REGISTRADOR 16 2.4.2 IMEDIATO 16 2.4.3 DIRETO 17 2.4.4 INDIRETO POR REGISTRADOR ( IMPLÍCITO ) 17 2.4.5 RELATIVO ( POR BASE ) 17 2.4.6 COM ÍNDICE 18 2.5 MODO DE ENDEREÇAMENTO EM CÓDIGO OBJETO 18 2.6 EXERCÍCIOS DE FIXAÇÃO 20 3 -EXERCÍCIOS DE PROGRAMAÇÃO 3.1 UTILITÁRIO DEBUG 21 3.1.1 COMO ENTRAR NO DEBUG 21 3.1.2 COMANDOS DO DEBUG 21 3.1.2. 1 COMANDO A 21 3.1.2. 2 COMANDO G 22 3.1.2. 3 COMANDO R 22 3.1.2. 4 COMANDO T 23 3.1.2. 5 COMANDO D 24 3.1.2. 6 COMANDO U 25 3.1.2. 7 COMANDO E 26 3.1.2. 8 COMANDO F 27 3.1.2. 9 COMANDO L 28 3.1.2.10 COMANDO M 28 3.1.2.11 COMANDO H 29 3.1.2.12 COMANDO N 29 3.1.2.13 COMANDO Q 29 3.1.2.14 COMANDO S 29 3.1.2.15 COMANDO C 30 3.1.2.16 COMANDO W 31 3.1.2.17 COMANDO I 32 3.1.2.18 COMANDO O 32 3.1.3 COMO CARREGAR UM PROGRAMA NA MEMÓRIA 32 3.2 INTERPRETAÇÃO DE PROGRAMAS 33 3.3 ELABORAÇÃO DE PROGRAMAS 38 3 PARTE 1 LINGUAGEM ASSEMBLY INTRODUÇÃO BIBLIOGRAFIA RECOMENDADA. Recomendamos aos senhores alunos que procurem consultar os livros abaixo relacionados para melhor entender esta parte do programa. Estes livros serviram como base de consulta para a preparação das aulas que se seguem. TÍTULO AUTOR(ES) EDITORA LINGUAGEM ASSEMBLY TAMIO SHIMIZU ALDO ARTUR BELARDI ORLANDO D. ONOFRE JR. ATLAS PROGRAMANDO EM ASSEMBLER 8086/8088 (IBM PC) EDISON RAYMUNDI JUNIOR JEREMIAS PEREIRA DOS SANTOS MAKRON BOOKS 8086/8088 HARDWARE/SOFTWARE APLICAÇÕES/PROJETOS WILSON ALONSO DIAS JR. McGRAW HILL 8086/8088 VOL. 1 SOFTWARE JOSÉ ANTONIO D. DE CARVALHO ROGÉRIO FELICIANO ROCHA ÉRICA ASSEMBLER - APRENDA COMO PROGRAMAR SEU PC ERIC PIERI RICARDO SCHOLZE ÉRICA LINGUAGEM ASSEMBLY PARA IBM PC PETER NORTON JOHN SOCHA CAMPUS 4 ARQUITETURA DO MICROPROCESSADOR DE 16 BITS Como já foi visto, em 1978 a Intel lançou o primeiro microprocessador de 16 bits, que foi o 8086. Este microprocessador tinha um desempenho interno de 16 bits e uma comunicação externa também de 16 bits, o que causava alguns problemas de comunicação pois a maioria dos periféricos existentes era de 8 bits. Por esse motivo, a Intel lançou no ano seguinte o microprocessador 8088 com o mesmo desempenho interno, mas com comunicação externa utilizando apenas 8 bits. MICROPROCESSADOR 8088 BARRAMENTOS Nome dado ao conjunto de fios paralelos que efetuam a ligação entre a CPU, Memória Primária e os periféricos de entrada e saída. Os barramentos são chamados ainda de "vias de comunicação" ou "bus". No 8088 temos três tipos de barramentos que nos interessam, que são : BARRAMENTO DE ENDEREÇO- Tem a função de localizar o endereço onde a informação será lida ou gravada. BARRAMENTO DE DADOS- Via por onde transitam os dados processados ou a serem processados. BARRAMENTO DE CONTROLE- Via por onde transitam os sinais que, entre outras coisas, dizem ao computador se no local indicado pelo barramento de endereço a informação deve ser lida ou gravada. DIAGRAMA EM BLOCO 5 DIAGRAMA DA CPU DO 8088 O 8088 esta dividido ao meio como se fosse dois processadores em uma mesma pastilha. Cada uma dessas divisões possuem nomes e funções diferentes : BIU ( Bus Interface Unit) Executa a comunicação com a memória e os periféricos do sistema. Suas funções são : buscar as instruções; ler ou escrever dados na memória ou periférico; arranjo seqüencial dos dados no registro Fila; busca ou armazenamento de operandos; realocação de endereços e controle de barramentos. EU- ( Execution Unit ) É a parte responsável pela decodificação e execução de todas as instruções do programa. Ela recolhe as instruções do registro FILA e as decodifica. Quando necessário gera endereços de operandos, transfere esses endereços para a BIU, solicitando ciclo de leitura ou gravação na memória ou em um dispositivo de E/S. Durante a execução da instrução a EU testa os FLAGS, alterando-os conforme o resultado da instrução corrente. 6 ARQUITETURA INTERNA DO 8088 REGISTRADORES Todos os registradores do 8088, com exceção do registrador de fila (QUEUE ) que tem 4 registros de 8 bits, os demais são de 16 bits e estão divididos em vários conjuntos. REGISTRADORES GERAIS Conjunto de registradores pertencentes a EU, e estão divididos em três grupos : a) registradores de dados - ( 4 registradores ) ; b) registradores de índice - ( 2 registradores ) ; c) registradores ponteiros - ( 2 registradores ) . Registradores de dados - Cada um dos quatro registros deste grupo pode ser dividido em dois registros de oito (8) bits cada. Sempre que o nome do registrador terminar com a letra X indica que estamos nos referindo ao registrador no seu todo, ou seja, aos 16 bits. Quando o nome terminar com a letra H (HIGH), estamos nos referindo as 8 posições mais altas do registrador, bits 8 a 15. E quando o nome terminar com a letra L (LOW), estamos nos referindo as 8 posições mais baixas do registrador, bits 0 a 7. 15 8 7 0 AX AH AL Registro acumulador BX BH BL Registrador base CX CH CL Registrador contador DX DH DL Registrador de dados Para operações de aritmética ou de lógica, qualquer um desses registradores pode ser utilizado, mas existem certos tipos de instruções que os utilizam com funções especializadas, como as que se seguem : AX -Accumulation ( Acumulador) Está envolvido com operações de entrada e saída de dados; tradução de códigos entre sistemas; operações de multiplicação ou divisão, que normalmente são necessários 32 bits; ajuste de decimais e operações com decimais codificadas em binário. ( Obs.- No assembly do 8088, a forma natural de representar valores é em hexadecimal ). BX - Base ( Base ) É freqüentemente usado para referenciar posições de memória, onde podem ser encontradas tabelas ou vetores. CX - Counter( Contador ) Utilizado em operações que se repetem por inúmeras vezes, como a rotação do conteúdo de um registrador, o número de bytes ou palavras de uma string , controle de "loop", e etc. . DX - Data ( Dados ) Usado em operações de multiplicação para armazenar parte de um produto de 32 bits ou em operações de divisão para armazenar restos. É usado também nas operações de E/S para especificar o endereço do PORT ( porto, ancoradouro, portal, portão, canal, abertura ). Registradores de Índices e Ponteiros Estes registradores são usados para armazenar valores, que somados aos endereços existentes nos registradores de segmento irão permitir a obtenção dos 7 endereços dos dados dentro dos segmentos de memória. O nome dado ao deslocamento do ponteiro de memória dentro dos segmentos é OFFSET . . ÍNDICES . . PONTEIROS DI índice destino BP ponteiro de base SI índice fonte SP ponteiro de pilha Os registradores índices são usados para o offset no segmento de dados, enquanto que os registradores ponteiros são usados para armazenar os deslocamentos no segmento de pilha (stack). Estes registradores podem ser utilizados em operações aritméticas, de forma que os valores resultantes podem ser utilizados como indicadores de offset. DI - Destination Index ( Índice de Destino ) Contém o complemento do endereço de memória, onde a informação deverá ser armazenada. SI - Source Index ( Índice Fonte ) Contém o complemento do endereço de memória de uma informação que deverá ser lida. BP - Base Pointer ( Ponteiro Base ) Permite o acesso a dados dentro do segmento de pilha, que lá foram deixados para serem manipulados por sub-rotinas. SP - Stack Pointer ( Ponteiro de Pilha ) Aponta a posição do topo da pilha de dados na memória. O SP é o registrador usado, implicitamente, pelas instruções assembly PUSH e POP que, respectivamente, armazena e recupera dados da pilha. PILHA - ( STACK ) É uma área da memória usada para armazenar dados que devem ser utilizados posteriormente. A pilha é muito usada na chamada e retorno de sub-rotinas, em ocorrências de interrupções, ou ainda, para guardar valores, que devido a imposição do programa, precisam ser alterados, mas posteriormente devem ser recuperados com seus valores originais REGISTRADORES DE SEGMENTOS Conjunto de quatro registradores localizados na BIU, onde ficam armazenados os endereços iniciais de cada segmento de memória a ser acessado pelo programa assembly. O 8088 possibilita a utilização de até 1 megabyte de memória primária, mas para isso ser possível é necessário dividi-la em segmentos de 64 Kbytes cada. Isso se deve ao fato dos registradores possuírem apenas 16 bits, o que permite representar de 0000 h até FFFF h, ou seja, de 00.000 d até 65.535 d ou 64 Kbytes. Os segmentos na memória pode ser distribuídos com áreas vazias intercaladas, contíguos, ou sobrepostos, mas sempre começando em um endereço divisível por 10 h. Para acessar todas as posições de uma memória com 1 megabyte ( de 00000 h até FFFFF h ) são necessários 20 bits, é justamente por isso que o sistema conjuga os registradores de segmento com os registradores de índice ou ponteiros para obter o endereço efetivo da memória Este processo todo pode ser descrito em três etapas : 8 a) Ao ser ligado, o sistema divide a memória do computador em quatro segmentos de 64 Kbytes cada um, pré-definidos pelo "reset". Essa divisão pode ser refeita pelo programador utilizando o utilitário DEBUG. b) Cada segmento terá seu endereço inicial anotado no respectivo registrador de segmentos, localizados na BIU. MEMÓRIA PRIMÁRIA REGISTRADORES DE SEGMENTOS Segmento de dados 5784 7211 Segmento extra A050 00000 h 57840 h 72110 h A0500 h B050 DS ES SS CS Segmento de pilha 64 Kb 64 Kb 64 Kb 64 Kb Segmento de códigos B0500 h c) Para transformar os endereços com 16 bits existentes no registrador para os de 20 bits efetivos da memória, o sistema efetua as seguintes operações : I ) multiplica o valor do registrador por 10 h, exemplo : Tomando o valor do registrador DS ( 5784 h ), teremos 5784 * 10 = 57840 h II ) soma o valor obtido com o existente em um dos registros índice ou ponteiro, exemplo : Supondo que desejamos chegar até a um dado localizado na memória primária no endereço 61892 h devemos colocar no registrador SI o valor A052 h, assim o offset será 57840 + A052 = 61892 h Os registradores de segmentos e as respectivas áreas na memória possuem os mesmos nomes, assim, DS pode representar tanto o registrador que se encontra na BIU, como o segmento que se encontra na memória. Os segmentos de memória possuem as seguintes funções : DS - ( Data Segment ) - Local da memória onde se encontram os dados, tais como as variáveis e áreas de trabalho do programa. ES - ( Extra Segment ) - Utilizado como segmento auxiliar do DS. Pode conter informações que não cabem no DS, ou que se registradas separadamente facilitam o seu acesso. 9 SS - ( Stack Segment ) - Local onde se encontra o segmento de pilha. CS - ( Code Segment ) - Segmento que armazena os códigos do programa que está sendo executado. REGISTRADORES DE CONTROLE São registradores que podem alterar o fluxo normal do programa, ativando ou desativando condições de desvio. Um deles é o IP que se encontra na BIU, e o outro é o registrador de FLAGS que está localizado na EU. IP - ( Instruction Pointer ) - Este registrador é controlado pelo próprio sistema, sendo acessível ao programador apenas com o uso de alguns comandos de desvio, como por exemplo, os comandos JUMP, CALL e J<condição>. O IP indica o offset a ser realizado no segmento de códigos ( CS ). Para localizar a próxima instrução do programa, o sistema efetua o seguinte cálculo : CS * 10 h + IP = endereço efetivo do comando FLAGS - Possuem a função de sinalizar os resultados de determinadas operações, permitindo ao sistema tomar decisões adequadas a cada caso. Dos 16 bits do registrador apenas 9 são utilizados. . 15 . 14 . 13 . 12 . 11 . 10 . 09 . 08 . 07 . 06 . 05 . 04 . 03 . 02 . 01 . 00 XX XXXX XX OF DF IF TF SF ZF XX AF XX PF XX CF Os flags estão divididos em dois grupos : FLAGS DE STATUS - CF, PF, AF, ZF, SF e OF FLAGS DE CONTROLE - TF, IF e DF CF - CARRY FLAG - ( sinalizador de transporte ) Indica o transporte do bit de mais alta ordem, após uma operação aritmética. Nas adições que geram o "vai um" ou nas subtrações que geram"empréstimo ", o CF será "setado ", ou seja, será igual a 1, caso contrario o CF será "ressetado , ou seja, será igual a 0. O CF é utilizado, também, nas operações de rotação e deslocamento. exemplo : adição subtração vai um para o número seguinte CF = 1 não empresta um do número seguinte CF = 1 não vai um para o número seguinte CF = 0 empresta um do número seguinte CF = 0 PF - PARITY FLAG - ( sinalizador de paridade ) Se o byte menos significativo do resultado de uma instrução lógica ou aritmética, apresentar uma quantidade PAR de bits ativados o PF será igual a 1, caso contrario será 0. exemplo : byte PF 1010 0011 � 4 bits ativados = 1 1100 1110 � 5 bits ativados = 0 10 AF - AUXILIARY FLAG - ( sinalizador auxiliar ) Se em uma adição houver um "vai um" ou em uma subtração o "empréstimo" de um entre os bits 3 e 4, o AF será igual a 1, caso contrário será igual a 0. O AF é utilizado, também, eminstruções de ajuste decimal. exemplo adição subtração bit # 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 � � 0 1 0 0 1 1 0 1 0 1 0 1 0 1 1 1 1 0 1 0 1 0 1 1 0 0 1 0 1 0 1 1 1 1 1 1 1 0 0 0 AF = 1 0 0 1 0 1 1 0 0 AF = 1 ZF - Zero Flag - ( sinalizador zero ) Indica o resultado de uma operação aritmética ou comparação lógica. Se o resultado for diferente de zero o ZF será = 0 Se o resultado for igual a zero o ZF será = 1 exemplo 0 1 0 1 0 1 1 1 - 1 0 1 0 1 1 1 1 - 0 0 1 0 1 0 1 1 1 0 1 0 1 1 1 1 0 0 1 0 1 1 0 0 �ZF = 0 0 0 0 0 0 0 0 0 �ZF = 1 SF - Sign Flag - ( sinalizador de sinal ) Contém o sinal resultante de uma operação aritmética. exemplo Se o resultado da operação for positivo � SF = 0 Se o resultado da operação for negativo � SF = 1 TF - Trap Flag - ( Sinalizador "passo a passo" ) Usado pelo sistema, quando for solicitado o modo "passo a passo". Uma situação característica é quando for necessária uma depuração em programa. Para se ativar o TF devemos fazer executar as seguintes instruções: MOV AX, 0100 � move para o acumulador o valor que irá zerar todos os flags, menos o TF. PUSH AX � coloca na pilha o valor do acumulador. POPF � move da pilha para os flags o valor 0100. IF - Interrupt-enable Flag - ( sinalizador de interrupções ) Este flag inibe ou não as interrupções externas. Se IF for igual a 1 as interrupções estarão habilitadas Se IF for igual a 0 as interrupções não estarão habilitadas. Interrupções externas provocadas pelo operador do sistema serão atendidas quando o IF estiver habilitado, caso contrário não serão atendidas. O IF é controlado pelas instruções assembly : STI ( start I ) � "setar" o IF ( permite interrupções ) CLI ( close I ) � "ressetar" o IF ( não permite interrupções ) 11 DF - Direction Flag - ( sinalizador de direção ) Indica a direção em que as instruções string devem ser processadas. Ele diz aos registradores SI e DI se devem avançar ou retroceder. Se DF for igual a 1, SI ou DI será auto-decrementado Se DF for igual a 0, SI ou DI será auto-incrementado O DF é controlado apenas pelas instruções assembly : STD ( start D ) � "setar" o DF CLD ( close D ) � "ressetar" o DF OF - Overflow Flag - ( sinalizador de excesso ) Indica se houve um "estouro" no resultado de uma operação aritmética. Se o resultado obtido excedeu ao tamanho da área destinada ao resultado, o OF ficará igual a 1, indicando que houve um "estouro". Se o resultado obtido não excedeu ao tamanho da área destinada ao resultado, o OF ficará igual a 0, indicando que não houve "estouro". EXEMPLOS I) Indicar os estados dos flags, após a realização da seguinte operação : 73 + ( - 6C ) a) transformar ( - 6C ) pelo complemento de dois - 0110 1100 � 1001 0011 + . 1 1001 0100 b) efetuar a soma 73 + 94 0111 0011 + 1001 0100 1 0000 0111 � = 07 Estado dos flags OF = 1 - houve "estouro" no tamanho do resultado ; SF = 0 - o resultado é positivo ; ZF = 0 - o resultado é diferente de zero ; AF = 0 - não houve "vai um" entre os bits 3 e 4 ; PF = 0 - há um número ímpar de bits ativados ; CF = 1 - houve um "vai um" para fora do resultado . 12 II) 34 + 2B Estado dos flags 0011 0100 + OF = 0010 1011 SF = ZF = AF = PF = CF = EXERCÍCIOS DE FIXAÇÃO 1a.) Quais são as diferenças entre os microprocessadores 8086 e8088 ? 2a.) Qual é a função do barramento de endereços ? 3a.) Para que serve o barramento de dados ? 4a.) O que transita pelo barramento de controle ? 5a.) O que é executado pela BIU ? Exemplifique. 6a.) Qual é a responsabilidade da EU ? Exemplifique. 7a.) Quantos bits possuem os registradores do 8088 ? Qual é a única exceção ? 8a.) Quais são os registradores de dados ? No que diferem dos outros ? 9a.) Como diferenciamos o manuseio dos registradores de dados, quanto a quantidade de bits e o local de acesso ? 10a.) Quais as funções do registro acumulador ? 11a.) Como é usado o registro base ? 12a.) Para que serve o registro contador ? 13a.) Como é usado o registro contador ? 14a.) O que é armazenado nos registradores de índice e de ponteiro ? 15a.) O que contém o registrador DI ? 16a.) O que contém o registrador SI ? 17a.) O que o registrador BP permite ? 18a.) O que aponta o registrador SP ? 19a.) O que é uma pilha ? 20a.) O que está gravado nos registradores de segmento ? 21a.) O que contém o segmento de memória DS ? 13 22a.) O que contém o segmento de memória ES ? 23a.) O que contém o segmento de memória SS ? 24a.) O que contém o segmento de memória CS ? 25a.) Para que servem os registradores de controle ? 26a.) O que controla o registrador IP ? 27a.) O que são FLAGS ? 28a.) O que indica o sinalizador CF ? Exemplifique. 29a.) O que indica o sinalizador PF ? Exemplifique. 30a.) O que indica o sinalizador AF ? Exemplifique. 31a.) O que indica o sinalizador ZF ? Exemplifique. 32a.) O que indica o sinalizador SF ? Exemplifique. 33a.) O que indica o sinalizador TF ? Exemplifique. 34a.) O que indica o sinalizador IF ? Exemplifique. 35a.) O que indica o sinalizador DF ? Exemplifique. 36a.) O que indica o sinalizador OF ? Exemplifique. 37a.) Demonstre como o 8088 chega as seguintes posições de memória : a) Como chegar aos dados existentes na posição de memória B5328, sendo que o registrador DS aponta para AADB. b) Se o dado desejado, encontra-se na posição de memória 35671, e o registrador SI apresenta o “offset” CD91, para qual endereço aponta o registrador DS. c) Se antes da execução de uma instrução de 4 bytes o registrador CS aponta para A5306, eo registrador IP para o “offset” 0805, após a execução da leitura desse comando, quais serão os novos valores desses registradores. 38a.) Como é ativado e desativado o flag "trap" (TF) ? 39a.) Como é "setado" e "ressetado" o IF ? 40a.) Como é "setado" e "ressetado" o DF ? 41a.) Indique o "status" dos flags OF; SF; ZF; AF; PF; CF, após cada uma das operações abaixo : a) 3251 + 0AF2 b) 45 + 3B c) 8A + 91 d) 3421 - 1250 e) 4854 - 3244 f) 3261 - 4154 g) 54 + AC 14 a b c d e f g OF = SF = ZF = AF = PF = CF = 15 PARTE 2 NOÇÕES PRELIMINARES Inicialmente, veremos algumas definições de termos já conhecidos, empregados na linguagem assembly. BYTE - Usado em alguns comandos para informar ao computador que uma determinada instrução irá manipular apenas 8 bits ( meia palavra ). WORD - Quando é necessário manipular de uma só vez dois bytes ( uma palavra ), inclui-se este termo à instrução. DWORD ( DOUBLE WORD )- usado em instruções que irão manipular 32 bits ( palavra dupla ). Em seguida veremos alguns termos novos empregados em assembly : ENDEREÇO LÓGICO - Endereços existentes nos registradores que isoladamente não apontam para nenhuma posição efetiva da memória. ENDEREÇO FÍSICO - É a localização do dado na memória. O endereço físico é obtido com a conjunção dos endereços lógicos do registrador de segmento com um dos registradores de índice ou de ponteiro. EA - ( EFFECTIVE ADDRESS ) Endereço Efetivo é a forma como normalmente nos referimos ao endereço físico do dado.ARMAZENAMENTO DE WORD NA MEMÓRIA Os oitos bits mais baixos de uma word ( bits 0 a 7 ) são os primeiros a serem transferidos para a memória, consequentemente, eles ocupam a posição de mais baixa ordem, enquanto que os bits seguintes ocupam a posição maior. EXEMPLO : Se armazenarmos na memória do computador a word com o valor 3A8F a partir do endereço 53201, teremos : a) primeiro passo - 0011 1010 1000 1111 � � 1000 1111 posição - 53200 53201 53202 b) segundo passo- 0011 1010 1000 1111 � � 1000 11110011 1010 posição - 53200 53201 53202 Dessa forma, a posição dos dados se invertem, a representação da word original no registrador que era 3A8F na memória ficou 8F3A. 16 Por esse motivo, a leitura de um “dump” dos programas em que os dados ora são tratados como word e ora como byte, devem merecer uma atenção toda especial do programador. ENDEREÇAMENTO Á MEMÓRIA Para poder acompanhar os exemplos dos diversos modos de endereçamento do assembly, é importante conhecer : 1º) A formula geral dos comandos. FORMULA GERAL ⇒ CÓDIGO DE OPERAÇÃO OPERANDO DESTINO , OPERANDO FONTE exemplo ⇒ MOV AL , BH Será movido o conteúdo do registrador BH para o registrador AL . 2º) Todas as vezes que acessarmos a memória, o valor existente no registro de segmento em uso, é automaticamente multiplicado por 10 h e somente depois somado ao valor do “offset”. ENDEREÇAMENTO POR REGISTRADORES Quando os dois operandos são registradores. Exemplo - MOV AX,BX Efeito - O conteúdo do registrador BX será transferido para o registrador AX. Desenvolvimento - Supondo que a instrução encontra-se no segmento de códigos, que se inicia na posição 0A000, e o comando MOV AX,BX, que ocupa 2 bytes esta localizado a partir da posição 0A100. Neste caso, o registrador CS aponta para o endereço 0A00 e o IP possui o deslocamento para mais 0100 posições. No momento anterior à execução da instrução, no registrador de dados BX estará o dado desejado, e no AX um dado qualquer. Após completado o comando, a situação dos registradores será a seguinte : CS - Continuará apontando para 0A00 . IP - Como o comando anterior era de dois bytes, ele passa a ter o valor 0102, indicando a posição da próxima instrução. BX - Continua tendo o valor anterior, que foi copiado em AX. AX - Terá uma cópia do valor existente em BX. ENDEREÇAMENTO IMEDIATO Quando o valor já faz parte da instrução ( valores constantes ). Exemplo - MOV AL,74 Efeito - O valor 0111 0100 será movido para AL MOV AX,5361 - O valor 0101 0011 0110 0001 será movido para AX Desenvolvimento - Os registradores CS e IP terão um desempenho idêntico ao caso anterior. ATENÇÃO - Os modos de endereçamento, que serão vistos a frente, apresentam um dos operandos entre colchetes, isso significa que o valor escrito ou gravado no registrador será utilizado como complemento do valor existente no registrador de segmento, a fim de se obter o EA. Fazemos este alerta, pois é comum surgirem erros de programação devido ao uso equivocado desses valores. 17 ENDEREÇAMENTO DIRETO O valor existente entre colchetes é somado ao valor do registrador de segmento de dados ( DS ). Neste caso, o valor opera como se fosse um registrador de índice. Dependendo da instrução, o endereço efetivo servirá para copiar ou fornecer dados. Exemplo - MOV CX,[ 7211 ] Efeito - Os dados existentes nas posições apontadas pela soma de DS + 7211 e DS +7212 serão copiado no registrador CX. MOV [ 8366 ],AH Efeito - O dado existente em AH será copiado na posição de memória apontada pela soma de DS e 8366. ENDEREÇAMENTO INDIRETO POR REGISTRO ( ENDEREÇAMENTO IMPLÍCITO ) Difere do endereçamento direto apenas na forma como ele é especificado. O deslocamento para se encontrar o EA é fornecido com a utilização de um registrador base ( BX ) ou por um registrador de índice ( SI , DI ), somado ao registrador DS. Exemplos - MOV AX,[ SI ] Efeito - O valor existente no registrador SI será somado ao valor existente em DS formando o EA. A informação existente nesse endereço e no seguinte serão copiadas no registrador AX. - MOV DH,[ BX ] Efeito - Será idêntico ao exemplo anterior, somente diferindo no registrador que irá provocar o deslocamento, que neste caso é o registrador de dados BX. - MOV [ DI ],AH Efeito - O dado existente em AH será copiado na posição de memória indicada pela soma dos registradores DS e DI. ENDEREÇAMENTO RELATIVO ( ENDEREÇAMENTO POR BASE ) O 8088 possui duas maneiras de endereçamento relativo, o endereçamento relativo a dados e o endereçamento relativo a stack. O primeiro utiliza o registrador de segmento DS e o segundo o registrador de segmento SS. Excetuando o endereçamento imediato, todas as demais formas de endereçamento podem utilizar este modo. Este método de endereçamento consiste em somar ou subtrair um valor do indicado pelos registradores utilizados para deslocamento ( BX, BP ). Acesso ao segmento de dados ( DS ) MODO RELATIVO DIRETO - É somado ao registrador BX um valor em hexadecimal. Exemplos - MOV AL,[ BX + 02 ] MOV [ BX - 0A ] ,AX MODO RELATIVO IMPLÍCITO - É somado ao registrador BX o valor de um dos índexadores ( DI ou SI ). Exemplos - MOV DX, [ BX + SI ] MOV [ BX + DI ] ,CL 18 MODO RELATIVO DIRETO INDEXADO - É uma mistura dos dois anteriores. Exemplos - MOV AX, [ BX + SI + 03 ] MOV [BX + DI+ 0512 ] , DH Acesso ao segmento de pilha ( SS ) As formas de acesso são idênticas às vistas acima, somente que o registrador base, que indica o local de acesso, é que muda, no lugar de BX é usado o registrador BP que é o registrador próprio para acessar dados na pilha. ENDEREÇAMENTO COM ÍNDICE É idêntico ao endereçamento relativo. A diferença reside no fato que ele utiliza os registradores índices ( SI ou DI ), em lugar dos registradores BX e BP. Exemplos - MOV [ DI + 10 ] , AX MOV DX, [ SI - 0102 ] MODO DE ENDEREÇAMENTO EM CÓDIGO OBJETO O 8088 utiliza um byte do código objeto como byte de endereçamento. Este byte, salvo algumas exceções, é o segundo byte do grupo de bytes que formam o comando. Assim em uma instrução temos : ⇒ o primeiro byte com o código de operação ; ⇒ o segundo byte com o código de endereçamento, sendo que neste byte pode ser associado mais um ou dois bytes, dependendo do deslocamento. . 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 . . bytes 3, 4, etc. código op D W modo reg R/M primeiro byte segundo byte ONDE : CÓDIGO OP → representa o código da instrução ; D → quando este campo for 0 , significa que o campo REG abriga o OPERANDO FONTE quando este campo for 1 , significa que o campo REG abriga o OPERANDO DESTINO ; W → quando W = 0, indica que o operando é um BYTE quando W = 1, indica que o operando é uma WORD ; MODO → indica se os dois operando são registradores ou se um deles está na memória, conforme tabela I abaixo ; REG → juntamente com o bit W , seleciona o registrador para a operação ( veja tabela II ) R/M → utilizado em conjunto com o campo MODO para especificar o modo de endereçamento ( tabela III ) . TABELA I - MODO 00 ⇒ Endereçamento à memória, sem byte de deslocamento` 01 ⇒ Endereçamento à memória, com deslocamento indicado em um byte. ( faixa de - 128 até + 127 ) . 10 ⇒ Endereçamento à memória, com deslocamento indicado por dois bytes 11 ⇒ Endereçamento ao registrador. 19 TABELA II - REG REG W=0 W=1 000 AL AX 001 CL CX 010 DL DX 011 BL BX 100 AH SP 101 CH BP 110 DH SI 111 BH DI TABELA III R/M . R/M MODO 00 ( sem desloc.) MODO 01 ( desloc. de 8 bits ) MODO 10 (desloc. de 16 bis) MODO 11 W=0 W=1 000 BX + SI BX + SI + Desloc. BX + SI +Desloc. AL AX 001 BX + DI BX + DI + Desloc. BX + DI+Desloc. CL CX 010 BP + SI BP + SI + Desloc. BP + SI + Desloc. DL DX 011 BP + DI BP + DI + Desloc. BP + DI +Desloc. BL BX 100 SI SI + Desloc. SI + Desloc. AH SP 101 DI DI + Desloc. DI + Desloc. CH BP 110 Acesso direto BP + Desloc. BP + Desloc. DH SI 111 BX BX + Desloc. BX + Desloc. BH DI EXEMPLOS DE ENDEREÇAMENTO EM CÓDIGO OBJETO # DE BYTES INSTRUÇÃO CÓDIGO OBJETO 1 LOCK 1111 0000 F 0 2 MOV AX,BX 1000 1001 1101 1000 8 9 D 8 3 MOV AX, [ 87E2 ] 1010 0001 1110 0010 1000 0111 A 1 E 2 8 7 4 ADD [ BP + DI + 0034 ] ,BH 0000 0000 1011 1011 0011 0100 0000 0000 0 0 B B 3 4 0 0 ADD [ 0002 ] , AX 0000 0001 0000 0110 0000 0010 0000 0000 0 1 0 6 0 2 0 0 MOV DI , [ 8BFB ] 1000 1011 0011 1110 1111 1011 1000 1011 8 B 3 E F B 8 B OBSERVAÇÃO Pode existir ainda comandos com 5 e 6 bytes. 20 EXERCÍCIOS DE FIXAÇÃO 1a.) O que é um endereço lógico ? 2a.) Como é obtido o endereço físico de uma informação ? 3a.) O que é um EA ? 4a.) Como uma word é armazenada na memória ? Exemplifique com a word 5681. 5a.) qual é a formula geral de um comando assembly ? 6a.) Descreva o efeito de cada uma das formas de endereçamento abaixo relacionadas. Crie pelo menos um exemplo. a) Endereçamento Direto. b) Endereçamento por Registradores. c) Endereçamento Relativo. c.I ) Direto Indexado. c.II ) Implícito. c.III ) Direto. d) Endereçamento Indireto por Registro. e) Endereçamento com Índice. f) Endereçamento Imediato. 7a.) O que significa quando um dos operandos do comando está entre colchetes ? 8a.) No endereçamento em código objeto, o que é anotado nos bits de 2 a 7 do primeiro byte ? 9a.) O que indica o campo D ( bit 1 do primeiro byte ) ? 10a.) Qual é a função do campo W ( bit 0 do primeiro byte ) ? 11a.) Descreva as funções dos campos do segundo byte, abaixo relacionados a) campo MODO ( bits 6 e 7 ). b) campo REG ( bits 3, 4 e 5 ). c) campo R/M ( bits 0, 1 e 2 ). 21 PARTE 3 EXERCÍCIOS DE PROGRAMAÇÃO UTILITÁRIO DEBUG O debug é um utilitário fornecido junto com o MS-DOS, que permite testar e depurar programas em assembly. Composto por dezoito comandos, todos representados pela primeira letra de seu nome. Como muitos comandos têm várias sintaxes, essas serão relacionadas quando da explicação de cada comando. Estes, por sua vez, podem ser escritos com letras maiúsculas ou minúsculas, indiferentemente, mas os dados numéricos devem ser inseridos em notação hexadecimal. Chamamos a sua atenção para o comando INT utilizado no final de cada programa. Existem várias formas de se encerrar um programa, mas algumas dessas formas devolvem o comando do sistema ao DOS, saindo automaticamente do debug, outras travam o computador, como por exemplo o comando HLT. Portanto, para permitir uma análise melhor do programa-exercício, recomendamos o uso do comando INT 3. ORIGEM DO TERMO DEBUG Segundo anotações feitas em relatório pela contra-almirante da marinha dos EEUU Grace M. Hopper, em 1945, época em que era capitã, quando desenvolvia um projeto usando computador, a máquina apresentou um curto-circuito. Depois de algum tempo de busca, foi encontrada uma mariposa ( bug ) caída entre os reles do computador. A remoção dessa mariposa deu origem ao termo DEBUG. Grace M. Hopper foi uma das primeiras pessoas a desenvolver programas para computador. Em 1959 foi a principal analista na criação da linguagem COBOL. Devido ao seu desempenho na área da informática, ela ficou conhecida como a “ surpreendente Grace “. Em 1986 ela se reformou com a patente de contra-almirante. COMO ENTRAR NO DEBUG Estando no DOS, deve ser digitado o comando DEBUG, com ou sem o nome do arquivo. Para os nossos exercícios não existe nome de arquivo. Na tela surgirá apenas um hífen que representa o “PROMPT” do debug. Exemplo : C : \ WINDOWS> debug < enter > - ROL DE COMANDOS DO DEBUG. Para se conhecer os comandos do debug, basta digitar após o hífen o sinal de interrogação ( ? ), que surgirá na tela uma relação de todos eles. -? assembler A < endereço > move M intervalo endereço compare C intervalo endereço name N < nome do caminho > dump D < intervalo > output O porta enter E endereço < lista > quit Q fill F intervalo < lista > register R < registrador > go G < =endereço > < endereço > search S intervalo lista hex H valor1 valor 2 trace T < =endereço> <valor> input I porta unassembler U < intervalo > load L < end. > < unidade > write W < end. > < unidade > 22 COMANDO A Deixa disponível a utilização de um mini-assembler do debug, o que permite ao usuário fazer pequenos programas. O comando A deve indicar a posição do primeiro comando dentro de CS, portanto sua sintaxe é : - A < endereço > , o endereço representa o offset que irá constar do registrador IP. No caso de se omitir o valor do offset, o sistema assumirá o endereço 0100 automaticamente. Exemplo : - A 100 < enter > Logo após ser digitado o "enter" , surgirão na tela oito dígitos, indicando o endereço do segmento de códigos ( CS ) e o valor do ponteiro de instruções ( IP ). EXEMPLO C : \WINDOWS > debug < enter > - A100 < enter > 0FDA : 0100 < local da primeira linha de comando > onde : 0FDA - indica a localização do segmento CS na memória. 100 - o valor do registrador IP, e que indica o "offset", corresponde a 256 decimal. Após cada "enter" surgirá na tela novo indicativo CS:IP. EXEMPLO Observe que o incremento do IP entre os três primeiros comandos é de dois bytes, já o incremento entre a linha de comando MOV [300] , AL e a linha INT 3 é de três bytes, por sua vez INT 3 é de apenas um byte. Esta observação pode ser confirmada no comando U, mais adiante. COMANDO G Executa o programa existente na memória. Se o programa acabou de ser digitado, basta digitar G , mas para evitar problemas o melhor é digitar G= <endereço inicial do programa> EXEMPLOS G <enter> ou G= 0100 <enter> Ao terminar a execução, se o último comando for INT 3, surgirá na tela o status de todos os registradores, como acontece com o comando R. COMANDO R Dependendo de como é escrito o comando, ele exibe no vídeo o conteúdo de todos os registradores e a próxima instrução do programa, ou apenas um determinado registrador, permitindo a alteração de seu valor. - A 100 0FDA : 0100 MOV AL,40 0FDA :0102 MOV AH,41 0FDA : 0104 ADD AL,AH 0FDA : 0106 MOV [ 300 ],AL 0FDA : 0109 INT 3 0FDA : 010A 23 As sintaxes do comando R podem ser : R < enter >⇒ Para mostrar o conteúdo de todos os registradores. Sempre que forem mostrados os registradores, será exibido o "status" dos flags conforme tabela abaixo : EXEMPLO -R AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0FDA ES=0FDA SS=0FDA CS=0FDA IP=0100 NV UP EI PL NZ NA PO NC 0FDA:0100 B040 MOV AL,40 R < registrador > <enter> ⇒Permite alterar o conteúdo de um determinado registrador. EXEMPLO Digita-se R IP ⇒ Será mostrado o conteúdo do IP. A tela ficará = R IP 010A : ⇒ Após os dois pontos digita-se o novo valor do IP. COMANDO T Executa um programa passo a passo. A cada instrução executada, ele mostra o conteúdo dos registradores exatamente como o comando R. Suas sintaxes são : T T = < endereço > Sintaxe T Para executar este comando é necessário reduzir o endereço existente no registrador IP, fazendo com que ele aponte para a posição desejada da memória. EXEMPLO Supondo a execução do programa acima. No seu final o registrador IP estará apontando para a posição 010A do segmento. Para podermos iniciar o “trace” na posição inicial do programa, devemos proceder da seguinte forma: Digita-se R IP A tela ficará R IP 010A Digita-se :0100 SETADO RESSETADO OVERFLOW OV NV DIRECTION DN UP INTERRUPT EI DI SIGN NG PL ZERO ZR NZ AUX. CARRY AC NA PARITY PE PO CARRY CY NC 24 Sintaxe T = < endereço> Digita-se T=0100 <enter> Em qualquer uma das sintaxes, a indicação do endereço se torna desnecessária após a primeira interrupção. Para continuar basta digitar o comando T . EXEMPLO -T=0100 AX=0040 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0FDA ES=0FDA SS=0FDA CS=0FDA IP=0102 OV UP EI NG NZ NA PE NC 0FDA:0102 B441 MOV AH,41 -T AX=4140 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0FDA ES=0FDA SS=0FDA CS=0FDA IP=0104 OV UP EI NG NZ NA PE NC 0FDA:0104 00E0 ADD AL,AH -T AX=4181 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0FDA ES=0FDA SS=0FDA CS=0FDA IP=0106 OV UP EI NG NZ NA PE NC 0FDA:0106 A20003 MOV [0300],AL DS:0300 – 5F “ “ . “ -T AX=4181 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0FDA ES=0FDA SS=0FDA CS=0FDA IP=010A OV UP EI NG NZ NA PE NC 0FDA:010A 59 POP CX COMANDO D Permite examinar os segmentos da memória primária. Ele exibe blocos de dados gravados na memória do computador. Existem quatro formas de sintaxes para este comando, entretanto os dados exibidos terão sempre as seguintes informações: 1) Um grupo de oito números hexadecimais separados no meio por dois pontos, formando dois conjuntos de quatro dígitos cada. O primeiro grupo representa o segmento da memória e o segundo representa o offset. 2) Seguem dezesseis bytes em notação hexadecimal separados por um hífen entre o oitavo e o nono byte. 3) Finalizando a linha, no canto direito do dump, será vista uma interpretação dos dezesseis bytes anotados. Os bytes imprimíveis serão exibidos, mas os não - imprimíveis serão representados por pontos. EXEMPLO 250D:0300 B0 40 B4 41 00 E0 A3 00-03 CC 59 23 74 19 3C 0D . @ . A . . . . . . Y # t . < . As sintaxes do comando dump são: D D < endereço inicial > D < endereço inicial > L < comprimento > D < endereço inicial > < endereço final > 25 Sintaxe D Ao se digitar D < enter >, serão exibidas oito linhas de dados. Na primeira vez que esta sintaxe for usada, o endereço inicial será o 0100. Se continuarmos a usar esta sintaxe, o próximo endereço inicial será o 0180, depois 0200 e assim por diante. EXEMPLO -D < enter > 250D:0100 B0 40 B4 41 00 E0 A3 00 - 03 CC 59 23 74 19 3C 0D . @ . A . . . . . . Y # t < . 250D:0110 74 15 F6 C7 20 75 06 3A - 06 94 D2 74 34 00 FC 24 t . . . u . : . . . t 4 . . $ 250D:0120 75 E6 80 F7 20 EB E1 5E - 58 C3 A1 69 D7 8B 36 6B u . . . . . ^ X . . I . . 6 k “ “ “ 250D:0170 3C 3F 75 05 80 0E A7 D8 – 02 3C 2A 75 05 80 0E A7 < ? u . . . . . . < * u . . . . Sintaxe D < endereço inicial > Destaca as linhas de dados a partir do byte indicado, exibindo-os até o fim do bloco. EXEMPLO -D 0115 < enter > 250D:0110 - - - - - 75 06 3A - 06 94 D2 74 34 00 FC 24 u . : . . . t 4 . . $ 250D:0120 75 E6 80 F7 20 EB E1 5E - 58 C3 A1 69 D7 8B 36 6B u . . . . . ^ X . . I . . 6 k “ “ “ 250D:0170 3C 3F 75 05 80 0E A7 D8 – 02 3C 2A 75 05 80 0E A7 < ? u . . . . . . < * u . . . . Sintaxe D < endereço inicial > L < comprimento > Exibe a quantidade de bytes indicados pelo comando complementar L. EXEMPLO -D 0120 L 5 < enter > 250D:0120 75 E6 80 F7 20 u . . . Observação . O comando L será descrito mais adiante. Sintaxe D < endereço inicial > < endereço final > Exibe os bytes das posições indicadas como inicial e final. EXEMPLO -D 0110 012F < enter > 250D:0110 74 15 F6 C7 20 75 06 3A - 06 94 D2 74 34 00 FC 24 t . . . u . : . . . t 4 . . $ 250D:0120 75 E6 80 F7 20 EB E1 5E - 58 C3 A1 69 D7 8B 36 6B u . . . . . ^ X . . I . . 6 k COMANDO U Este comando permite recriar um arquivo fonte assembly partindo dos códigos em linguagem de máquina. O comando U “disassembla” o programa. Suas sintaxes são: U U < endereço inicial > L < comprimento > 26 U < endereço inicial > < endereço final > Sintaxe U Se no comando não for especificado o tamanho da área a ser “ disassemblada “, o debug assume a quantia de trinta e dois bytes. EXEMPLO -U 250D:0100 B049 MOV AL,40 250D:0102 B441 MOV AH,41 250D:0104 00E0 ADD AL,AH 250D:0106 A20003 MOV [300],AL 250D:0109 CC INT 3 250D:010A 59 POP CX 250D:010B 237419 AND SI,[SI+19] 250D:010E 3C0D CMP AL,OD 250D:0110 7415 JZ 011D 250D:0112 F6C720 TEST BH,20 250D:0115 7506 JNZ 011D 250D:0117 3A0694D2 CMP AL,[D294] 250D:011B 7434 JZ 0151 250D:011D 00FC ADD AH,BH 250D:011F 2475 AND AL,75 Sintaxe U < endereço inicial > L < comprimento > Será “ disassemblada “ somente a quantidade de bytes indicada. EXEMPLO -U 0104 L 7 250D:0104 00E0 ADD AL,AH 250D:0106 A20003 MOV [300],AL 250D:0109 CC INT 3 250D:010A 59 POP CX Sintaxe U < endereço inicial > < endereço final > Serão “disassembladas “ somente as linhas de comando solicitadas. EXEMPLO -U 0110 0117 250D:0110 7415 JZ 011D 250D:0112 F6C720 TEST BH,20 250D:0115 7506 JNZ 011D 250D:0117 3A0694D2 CMP AL,[D294] COMANDO E Este comando permite inserir ou modificar dados no conteúdo de um arquivo que se encontra na memória do computador. O comando E possui três modos de operação : E < endereço inicial > < lista > E < endereço inicial > < string > E < endereço inicial > Sintaxe E < endereço inicial > < lista > Os valores da lista devem estarescritos em hexadecimal e separados, por pelo menos, um espaço e não podem exceder a 80 caracteres. 27 EXEMPLOS : -E 0400 02 04 06 08 A C E 10 -D 0400 L 8 250D:0400 02 04 06 08 0A 0C 0E 10 - Sintaxe E < endereço inicial > < strig > Os caracteres a serem inseridos devem estar escritos entre aspas. Este comando aceita, além dos caracteres alfanuméricos, também, intercalados, os caracteres de controle EXEMPLO -E 0400 “UNIVERSIDADE” 0D 0A “SÃO JUDAS” 0D 0A “TADEU” 0D 0A 1A -D 0400 0420 250D:0400 55 4E 49 56 45 52 53 49 – 44 41 44 45 0D 0A 53 C7 UNIVERSIDADE .. S . 250D:0410 4F 20 4A 55 44 41 53 0D – 0A 54 41 44 45 55 0D 0A O JUDAS .. TADEU . . 250D:0420 1A . Sintaxe E < endereço inicial > Esta sintaxe não apresenta nenhuma lista de valores. Pressionada a tecla <enter>, o debug exibe o valor existente no endereço referido, permitindo que ele seja alterado ou não. Para alterar o dado, digita-se ao seu lado o novo valor e para seguir para o próximo endereço pressiona-se a barra-de-espaço. Para terminar ao debug basta pressionar a tecla <enter>. Se desejar se certificar da alteração, basta pressionar a tecla de hífen ( - ) que será exibida na linha seguinte a ( s ) alteração ( ões ) realizadas ( observe as duas alterações na primeira linha do exemplo abaixo). EXEMPLO -E 0100 250D:0100 5E. C3. 50. 32 56. 53 - 250D:0102 32. 53. 33. C9. 33. DB 250D:0108 AC. E8. COMANDO F Comando usado para preencher blocos de dados na memória. Suas sintaxes são : F < endereço inicial > L < comprimento > < lista de dados > F < endereço inicial > < endereço final > < lista de dados > A lista de dados deve conter ao menos um byte e a quantidade máxima deve corresponder ao tamanho da linha de comando do debug. Se a quantidade de dados existentes na lista for inferior ao comprimento indicado pelo comando L ou o obtido pela diferença entre os endereços inicial e final mais um, o preenchimento do bloco será efetuado, automaticamente pelo debug, repetindo os dados relacionados na lista de dados. Quando a lista de dados for um “string” os dados devem ser colocados entre aspas. F <<<< endereço inicial >>>> L < comprimento > < lista de dados > EXEMPLO -F 0150 L F “ UNIVERSIDADE “ -D 0150 L F 250D:0150 55 4E 49 56 45 52 53 49 – 44 41 44 45 55 4E 49 _ UNIVERSIDADEUNI 28 F <<<< endereço inicial >>>> < endereço final > < lista de dados > EXEMPLOS -F 0160 0170 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -D 0160 0170 250D;0160 00 01 02 03 04 05 06 07 - 08 09 10 11 12 13 14 15 … … … … … . 250D:0170 16 -F 016A 0170 A B C D E F 10 -D 0160 L 10 250D;0160 00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F … … … … … . 250D:0170 10 COMANDO L Este comando pode ser usado de duas formas. A primeira, junto com os comandos C, D, F, M e U para indicar o tamanho das áreas em operação. Na segunda, após o comando N, para efetuar a carga ( load ) do arquivo nomeado pelo comando N. Neste caso, o comando L poderá vir acompanhado por um indicativo do endereço inicial da memória, onde se efetuará a carga. Caso esse endereço não seja indicado a carga se dará no endereço 0100. A vantagem de se indicar o endereço inicial é a de se poder carregar vários arquivos na memória, possibilitando comparações entre eles. COMANDO M Utilizado para copiar um bloco de dados existentes em um endereço de memória em outro endereço. A sintaxe pode ser escrita de duas formas, mas o resultado será sempre igual. 1ª) M <endereço-fonte início> <endereço-fonte final> <endereço-destino início> 2ª) M <endereço-fonte início> L <comprimento> <endereço-destino início> O uso do comando L implica a necessidade de se conhecer a extensão do bloco fonte. Neste caso, devemos efetuar o seguinte cálculo: - Subtrai-se do endereço-fonte final o endereço-fonte inicial e em seguida soma-se um ao resultado. EXEMPLO Supondo que desejamos copiar os valores existentes no bloco formado pelas linhas de dados 0100 e 0110 com um total de 32 bytes, para as posições começando no endereço 2BC0, o raciocínio a ser desenvolvido será o seguinte : Endereço-fonte final 011F Endereço-fonte inicial 0100 – 1F = 31 decimal 1 20 = 32 decimal O comando usando L ficará assim : -M 0100 L 20 2BC0 E sem o L ficará com este formato : -M 0100 011F 2BC0 29 COMANDO H Efetua a soma e a subtração entre dois números hexadecimais. Este comando aceita números de até quatro dígitos, e a saída é também de até quatro algarismos. Se o resultado tiver uma quantidade maior de dígitos, o de maior valor será desprezado. A sintaxe é : H < 1º número > < 2º número > EXEMPLOS 1º) -H 8756 A34B 2AA1 E40B ⇒ 2AA1 - é parte do resultado da adição, que seria 12AA1. E40B - é a diferença obtida com a operação 8756 - A34B, ou seja, a subtração de um número maior de um menor, portanto o resultado é negativo. 2º) -H 3581 1234 47B5 234D ⇒ 47B5 – é o resultado da soma dos dois números 234D – é a diferença entre os dois números. 3º) -H 2897 2897 512E 0000 ⇒ 0000 - Como os dois números são iguais, a diferença é zero. 4º) -H FFFF 0001 0000 FFFE ⇒ 0000 – é o resultado truncado da adição, pois o resultado completo seria 10000 5º) -H FFFE FFFF FFFD FFFF ⇒ FFFD – é o resultado truncado da adição, o certo seria 1FFFD FFFF – o resultado desta subtração, em decimal é -1. Lembre-se que o computador opera no sistema de Complemento de Dois. COMANDO N Comando utilizado para nomear um arquivo. Quando se desejar carregar um arquivo na memória, usa-se o comando N para identificá-lo ( veja o item “Como carregar um arquivo na memória” ). O comando N pode ser usado também para auxiliar o comando W, no caso de haver dúvidas sobre o arquivo a ser gravado. A sintaxe do comando é : N < nome do arquivo > COMANDO Q Comando usado para sair do debug . Sua sintaxe é : Q < enter > COMANDO S Executa a busca de um byte ou de uma string em um bloco de dados. A sintaxe para indicar os dados numéricos é diferente da sintaxe usada para dados alfanuméricos 30 As sintaxes são as seguintes : Para dados numéricos – -S < endereço inicial > L < comprimento > < lista de valores > Para string – -S < endereço inicial > < “ string “> -S < endereço inicial > L < comprimento > < “ string” > Busca Numérica A ausência da indicação do comprimento da área, provocará uma mensagem de erro, como demonstrado abaixo. -S 300 8B σ ERROR Lembre-se que o comprimento deve ser anotado em hexadecimal. EXEMPLO Se desejarmos saber onde e quantas vezes o número 8B está gravado no bloco de dados, que inicia no offset 0300, devemos indicar o L com o valor 80, que corresponde as 128 posições que compõem o bloco. O resultado da pesquisa é listado logo abaixo do comando. -S 300 L 80 8B 250B:0303 250B:0305 250B:031C 250B:033F 250B:0356 250B:0371 Busca Alfanumérica Na busca de uma string, devemos tomar cuidado com o tipo de letra que os dados estão gravados, lembre-se que os códigos ASCII das letras minúsculas são diferente dos códigos dessas mesmas letras maiúsculas Ex. A = 41 e a = 61 Uma outra precaução a ser tomada é que a string deve ser escrita entre aspas. EXEMPLO Supondo que exista no bloco, iniciado em 0400, várias vezes a palavra Universidade, a busca pode ser feita das seguintes formas : -S 400 “Universidade” ou -S 400 L 80 “Universidade” Observação - Se no bloco pesquisado, existir uma string no formato UNIVERSIDADE, ela será ignorada. Se no bloco pesquisado, não existir uma stringigual, aparecerá no final da busca apenas o prompt do debug. COMANDO C Compara dois blocos de memória. É importante que os dois blocos possuam o mesmo tamanho. As sintaxes deste comando são : 31 C <endereço inicial do 1º bloco> <endereço final do 1º bloco> <endereço inicial do 2º bloco> Ou C < endereço inicial do 1º bloco> L <comprimento> <endereço inicial do 2º bloco> O endereço final do segundo bloco é determinado pelo próprio debug. A listagem resultante da pesquisa, somente será feita se for encontrada alguma diferença entre os dois blocos. Se não houver qualquer divergência entre eles, aparecerá apenas o prompt do debug. Qualquer uma das sintaxes produz o mesmo resultado, e quando for encontrada uma diferença, a listagem será composta de quatro campos, com os seguintes significado : 1º campo – endereço do 1º campo; 2º campo – valores do 1º campo; 3º campo – valores do 2º campo; 4º campo – endereço do 2º campo. EXEMPLO Suponhamos que desejamos verificar se todos os valores existentes nos blocos 0600 e 0700 são iguais. Se alguma posição não combinar, o resultado será algo parecido com a listagem abaixo: -C 0600 L 80 0700 250D.0615 01 08 250D:0715 250D.0616 02 09 250D.0716 250D.0632 00 05 250D.0732 250D.0633 01 06 250D.0733 250D.0661 06 00 250D.0761 250D.0663 09 05 250D.0763 250D.0668 07 04 250D.0768 COMANDO W Grava em disco um arquivo. A gravação será feita no drive default, que normalmente é o drive C. Mas se o usuário desejar gravar no debug pelo drive A, usando o seguinte comando : A:\ WINDOWS> DEBUG < nome do arquivo> <enter> Ou se o arquivo se encontrar no HD, fica mais simples gravá-lo de volta no HD e depois copiá-lo para o disquete.( Consulte o item “COMO SOLICITAR UM ARQUIVO JÁ GRAVADO” ). Para gravar um arquivo, devemos colocar no registrador CX a quantidade de bytes que serão gravados, usando o comando R, em seguida digitar W . - A 100 0FDA : 0100 MOV AL,40 0FDA : 0102 MOV AH,41 0FDA : 0104 ADD AL,AH 0FDA : 0106 MOV [ 300 ],AL 0FDA : 0109 INT 3 0FDA : 010A -R CX CX 0000 : A -N (nome do arquivo ) -W Gravando 00A bytes 32 O comando W pode, também, gravar a partir de um determinado setor do HD ou disquete, mas esta operação é um tanto perigosa, pois é necessário o fornecimento de várias coordenadas com precisão rigorosa. Apesar de ser possível realizar esta operação, ela não é recomendada. COMANDO I Recebe e exibe um byte de um port de I/O especificado. A sua sintaxe é: -I < endereço do port > < enter > COMANDO O Envia um byte especificado, para um port de I/O especificado. A sua sintaxe é : -O < endereço do port > , < byte > < enter > COMO SOLICITAR UM ARQUIVO JÁ GRAVADO Uma das formas utilizadas, para se efetuar a carga de um arquivo na memória do computador, é dar o nome do arquivo junto com a chamada do programa debug. C : \ WINDOWS > DEBUG < nome do arquivo > < enter > A carga se dará no segmento default e na posição 0100. A outra forma de se carregar um arquivo é usar uma combinação na seqüência abaixo descrita. 1º) Usar o comando N para identificar o arquivo. 2º) Usar o comando L com ou sem o parâmetro de endereço. 3º) Se desejar saber o tamanho do arquivo, consultar os registradores BX e CX usando o comando R ( veja mais abaixo como ler esses dois registros ). EXEMPLO -N FLORESTA.BMP ⇒ Este comando apenas localiza o arquivo no disco. -L 0900 ou -L ⇒ Se não for indicado o endereço para a carga do arquivo, ela será feita em 0100. -R ⇒ Para se conhecer o tamanho do arquivo AX=0000 BX=0000 CX=0262 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=0FDA ES=0FDA SS=0FDA CS=0FDA IP=0100 OV UP EI NG NZ NA PE NC 0FDA:010A 59 POP CX Para se ler o tamanho do arquivo nos registradores BX , CX deve-se observar o seguinte : Se o arquivo tiver até FFFF bytes ( 65535 em decimal ), o tamanho do arquivo estará indicado somente no CX, o BX será igual a zero. Se o arquivo for igual ou maior que 64 Kb ( 10000 hexadecimal ou 65536 decimal ), a quantidade de vezes que o arquivo ultrapassar 64Kb será anotado no registrador BX , e os bytes restantes no registrador CX. EXEMPLO Supondo que um arquivo tenha um total de 133.523 bytes, os registradores exibirão os seguintes valores : BX= 0002 CX= 0993 Basta juntar os valores e o resultado será 20993 bytes, que correspondem a 133.523 bytes em decimal. Para se acessar um byte que se conhece o endereço em decimal, devemos converter o valor decimal em hexadecimal e subtrair 1, pois a primeira posição do arquivo, fatalmente, estará no endereço com final zero. Comentário: 33 EXEMPLO Se desejarmos acessar o centésimo byte de um arquivo, inicialmente converteremos o número 100 decimal em hexadecimal, obtendo o número 64 h. Esta seria a posição do centésimo byte, se a carga do arquivo tivesse sido feita a partir de um endereço finalizando com xxx1, mas como a carga é feita normalmente a partir de um endereço finalizando com xxx0, um dump da posição 64 h forneceria o valor do byte da posição 101 (decimal), portanto devemos subtrair um de 64 h e efetuar o dump da posição 63 h. Supondo, que a carga do arquivo foi iniciada no endereço 0100, o comando será : -D 0163 L 1 EXERCÍCIOS DE INTERPRETAÇÃO DE PROGRAMAS Analise os programas abaixo e comente cada linha de comando e no final escreva o enunciado do programa. Exemplo: PROGRAMA ANOTAÇÕES 25A2:0100 MOV BX,3500 ⇒ -move o valor 3500h para o registrador base BX 25A2 :0103 MOV CX,5A ⇒ -move o valor 5Ah para o registrador CX 25A2:0106 MOV AL,[ BX ] ⇒ -move os dados localizados no endereço DS:3500 . para o acumulador AL 25A2:0108 ADD AL,07 ⇒ -adiciona o valor 07h no valor colocado no . acumulador AL . 25A2:010A MOV [ BX ],AL ⇒ -devolve o dado para o endereço DS:3500 . 25A2:010C INC BX ⇒ -incrementa 01 no valor de BX 25A2010D LOOP 0106 ⇒ -decrementa 1 de CX. Se CX chegou a ZERO o programa termina, caso contrario retorna ao comando com o endereço 0106 . 25A2:010F INT 3 -termina o processamento, permanecendo no debug 25A2:0110 < enter > ⇒ -última linha do programa. O "enter" indica o fim ENUNCIADO –Desenvolva um programa para ler 90 valores armazenados na memória, a partir do endereço DS:3500h.. Após somar o valor constante 07, o dado deve ser devolvido a sua posições de origem. PROGRAMA # 1 Para executar este exercício, realize a seguinte preparação :- 1º) usando o comando R, mova o valor 0300 para o registro SI ; 2º) em seguida, usando o comando F, mova para as posições de memória 0300 até 030F 16 números em hexadecimal . 3º) Inicie a execução do programa a partir da posição 0100 ; 4º) ao final confira o valor existente no registro AX. ANOTAÇÕES 25A2:0100 MOV CX,10 ⇒ 25A2:0103 MOV AX,0 ⇒ 25A2:0106 MOV BH,0 ⇒ 25A2:0108 MOV BL,[ SI ] ⇒ 34 25A2:010A INC SI ⇒ 25A2:010B ADD AX,BX ⇒ 25A2:010D LOOP 0108 ⇒ 25A2:010F INT 3 ⇒ 25A2:0110 < enter > ENUNCIADO :- PROGRAMA # 2 Para executar este exercício, realize a seguinte preparação : 1º) preencha as posições de memória entre os endereços 3500 e 355A com o valor FF ; 2º) em uma posição qualquer, entre 3500 e 355A introduza um valor diferente . 3º) Inicie a execução do programa no endereço 0100; 4º) ao terminar o processamento, analise os registros AX,CX e IP. ANOTAÇÕES 25A2:0100 MOV BX,3500 ⇒ 25A2:0103 DEC BX ⇒ 25A2:0104 MOV CX,5A ⇒ 25A2:0107 INC BX ⇒ 25A2:0108 MOV AL,[BX] ⇒ 25A2:010A CMP AL,FF ⇒ 25A2:010C LOOPE 0107 ⇒ 25A2:010E INT 3 ⇒ 25A2:010F < enter > ⇒ ENUNCIADO : 35 PROGRAMA # 3 O programa abaixo efetue uma soma entre dois valores que ocupam 4 bytes cada um e que se encontram nas posições DS:2021h e DS:2025h, respectivamente o primeiro e o segundo operando. O resultado deverá ser salvo a partir da posição DS:2030h desse mesmo segmento. Analisar o programa e informe os valores das operações realizadas. Para executar este programa preencha as posições de memória 2021 até 2028 com os valores abaixo relacionados. No final verifique os resultados nas posições 2031 até 3033. Valores do 1o. operando Valores do 2o. operando posição - DS:2021 ⇒ A2 posição - DS:2025 ⇒ 78 - DS:2022 ⇒ CB - DS:2026 ⇒ 9E - DS:2023 ⇒ 32 - DS:2027 ⇒ 84 - DS:2024 ⇒ 1C - DS:2028 ⇒ 51 ANOTAÇÕES 25A2:0100 MOV CX,0004 ⇒ 25A2:0103 MOV SI,0000 ⇒ 25A2:0106 CLC ⇒ 25A2:0107 MOV AL,[ SI + 2021 ] ⇒ 25A2:0108 ADC AL,[ SI + 2025 ] `⇒ 25A2:010F MOV [ SI + 2030 ],AL ⇒ 25A2:0113 INC SI 25A2:0114 LOOP 0107 ⇒ 25A2:0116 INT 3 ⇒ 25A2:0117 < enter > ⇒ VALORES FINAIS DS:2030 DS:2031 DS:2032 DS:2033 ATENÇÃO- Os exemplos #4 e #5 estão escritos para rodarem em computadores analógicos. PROGRAMA # 4 Em um certo processo, deseja-se checar a temperatura de um sensor, e acionar lâmpadas de acordo com o valor medido. Se : a temperatura for < que 30°C → acender luz amarela a temperatura estiver entre 30°C e 40°C → acender luz verde a temperatura for > que 40°C → acender luz vermelha 36 → endereço do port de entrada para a temperatura FFFBh → endereço do port de saída para as lâmpadas FFFDh → códigos para acender as lâmpadas � luz amarela = acionar o bit 0 luz verde = acionar o bit 1 luz vermelha = acionar o bit 2 Descreva o que realiza cada comando. 5A2:0100 MOV DX,0FFFB 25A2:0103 IN AL,DX 25A2:0104 MOV DX,0FFFD 25A2:0107 CMP AL,1E 25A2:0109 JB 0113 25A2:010B CMP AL,28 25A2:010D JBE 0117 25A2:010F MOV AL,04 25A2:0111 JMP 0119 25A2:0113 MOV AL,01 25A2:0115 JMP 0119 25A2:0117 MOV AL,02 25A2:0119 OUT DX,AL 25A2:011A JMP 0100 25A2:011C PROGRAMA # 5 Suponha um processo, em que um computador tenha que controlar a velocidade de uma máquina, mantendo-a em um valor específico de 255 rotações por segundo. Se houver uma tendência da máquina em aumentar a velocidade, o computador desliga uma determinada chave até a velocidade voltar ao normal, quando então torna a ligá-la. Os endereços dos ports são : de entrada do valor da velocidade = FFF5h de saída do controle da chave = FFF8h Os códigos de controle são : para ligar a chave � 88h para desligar a chave � 00h 37 Descreva o que realiza cada comando. 25A2:0100 MOV DX,0FFF5 25A2:0103 IN AL,DX 25A2:0104 MOV DX,0FFF8 25A2:0107 CMP AL,FF 25A2:0109 JA 010F 25A2:010B MOV AL,88 25A2:010D JMP 0111 25A2:010F MOV AL,00 25A2:0111 OUT DX,AL 25A2:0112 JMP 0100 25A2:0114 PROGRAMA # 6 Comente as operações e indique os valores finais nos registradores AL e CL . ANOTAÇÕES 25A2:0100 MOV CL,11 25A2:0102 MOV AL,00 25A2:0104 DEC CL 25A2:0106 ADD AL,CL 25A2:0108 CMP CL,01 25A2:010B JAE 0104 25A2:010D INT 3 25A2:010E < enter > Valores finais � AL = CL = 38 Desenvolva programas para os exercícios abaixo. Exercício # 1 -Elabore um programa que preencha o segmento de dados, entre os endereços DS:0100h e DS:01FFh, com o byte 7Ch. Exercício # 2 -Elabore um programa que preencha o segmento de dados, entre os endereços DS:0500h e DS:05FFh, com a word A5C2h de forma que C2h fique nos endereços pares e A5h nos endereços ímpares. Exercício # 3 -Escreva um programa, que armazene nas posições de memória DS:3510h até DS:3530h os valores de 01 a 32. Exercício # 4 - Escreva um programa, que armazene nas posições de memória DS:1540h até DS:1560h os valores de 01 a 32 na ordem inversa. 5ª) Elabore um programa que armazene no Segmento de Dados, a partir da posição 0300, os dezesseis primeiros números pares, ou seja os números de 02 até 32. 6ª) Elabore um programa que armazene no Segmento de Dados, a partir da posição 0300, os dezesseis primeiros números impares, ou seja os números de 01 até 31. 7ª) Elabore um programa que leia dezesseis valores de 8 bits cada, armazenados a partir da posição de memória 0300, somando-os no registrador BX, de tal forma que ao final do processamento será possível ler o valor total tabulado no Registrador Base. 39
Compartilhar