Baixe o app para aproveitar ainda mais
Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original
* * Prof. Dr. Remy Eskinazi IFPE / UPE Programação Assembly 8086/8088 * * Introdução Assembly - linguagem que surgiu para representar as instruções por símbolos e não por números (linguagem simbólica), conhecida como linguagem de montagem. Qual o mais fácil de lembrar 10101011 ou ADD ? Necessidade de conversão dos símbolos para linguagem de máquina, linguagem que o µP entende. O processo de conversão (tradução) é chamado de montagem e é realizada por um programa denominado Montador (assembler). * * Montagem de Programa * * Montagem de Programa Principais funções: substituir código de operações simbólicas substituir nomes simbólicos de endereços reservar espaço de memória converter constantes examinar a correção de cada instrução * * Características da Programação Assembly Declaração e uso de label (corresponde a uma posição de memória e substitui um endereço); Existência de diretivas do montador (pseudo instruções ou comandos do montador) Existem diversos montadores para uma mesma arquitetura - MASM, TASM, EMU8086 ... Definição de áreas de memória (código, dados, etc) Segmentação de memória * * Segmentação de Memória A arquitetura dos processadores x86 usa segmentos de memória para gerenciar a informação, o tamanho destes segmentos é de 64Kb. O tamanho máximo de um número que o processador pode gerenciar é dado por uma palavra de 16 bits ou registrador, não sendo possível acessar mais do que 64k locais da memória apenas com um destes registradores. Sendo a memória do PC dividida em grupos de segmentos, cada um com 64k locais, e podemos usar um endereço ou registrador exclusivo para encontrar cada segmento, e ainda fazemos cada endereço com dois registradores. É possível acessar a quantidade de 4.294.967.296 bytes de memória. Para que o montador seja capaz de gerenciar os dados, é necessário que cada informação ou instrução se encontre na área correspondente ao seu segmento. O endereço do segmento é fornecido ao montador pelos registradores DS, ES, SS e CS. * * Segmentação de Memória * * Registradores IA32 / X86 15 8 7 0 EAX AH AL EBX BH BL ECX CH CL EDX DH DL ESP EBP ESI EDI EIP EF CS DS SS ES FS GS 16 31 acumulador base contador dado ponteiro para pilha ponteiro base índice fonte índice destino apontador de instruções flags segmento de código segmento de dados segmento de pilha segmento extra segmento extra segmento extra AX: BX: CX: DX: * * Registradores IA32 / X86 1) Os registradores de uso geral são registradores de 16 bits e podem ser divididos em dois registradores de 8 bits. São eles: AX - acumulador AH AL BX - base BH BL (utilizado em modos de endereçamento). CX - contador CH CL (utilizado como contador de operações de string) DX - dados DH DL * * Registradores IA32 / X86 2) Os registradores de ponteiros e endereços são: SP - stack pointer BP - base pointer - utilizados como apontador para acesso a diversos tipos de dados. SI - source index (índice e origem) DI - destination index - utilizados para acessar dados no segmento de dados. * * Registradores IA32 / X86 3) Os registradores de segmento de 16 bits são: CS - code segment - segmento de código corrente DS - data segment - segmento de dados SS - stack segment - segmento da pilha ES - extra segment - segmento extra utilizado como registrador. * * Registradores IA32 / X86 4) Flags são utilizados para armazenar informações sobre o status do processador. Normalmente são utilizados para setar dados após a execução de instruções lógicas e aritméticas. São eles: CF - carry flag 1 - ocorreu carry 0 - não PF - parity flag 1 - número par de 1 0 - ímpar AF - auxiliar flag 1 - ocorreu carry em operação bcd no dígito menos significativo. 0 - não ZF - zero flag 1 - resultado é zero 0 - não SF - signal flag 1 - negativo 0 - + OF - overflow flag 1 - ocorreu overflow 0 - não TF - trap flag - executa um programa passo a passo IF - interrupt flag 1 - interrupções habilitadas 0 - não DF direction flag 1 - crescente 0 - decrescente * * Modos de Endereçamento Imediato: operando é uma constante que segue o código de instrução. ex: mov bl,100 Registrador: operandos são registradores. ex: mov bl,ah Direto: operando localiza-se em um endereço específico na instrução (uma variável criada pelo programador) ex: add ax, varnum Indireto: operando localiza-se em um endereço apontado por um registrador base ou índice (BP,SI,DI). ex: mov cx,[di] Base: o endereço é dado pela soma do registrador base BP mais o deslocamento. ex: add ax,[bp+deslocamento] Indexado: o endereço é dado pela soma do registrador de indice SI ou DI mais um deslocamento. ex: add ax,[si + deslocamento] Indireto com base e índice: o endereço é dado pela soma de um registrador de segmento mais um registrador de base mais um registrador de índice. ex add ax,[bp+di+deslocamento]. * * Exercício: Baseado no trecho de código indicado na coluna Programa e nos dados de registradores, variáveis e memória, complete as colunas ax e Modo End. (endereçamento): bp = 0 0 0 2h = ( Definido na área de dados ) * * Tipos de Instrução Movimento de dados move dados na memória e em registradores da CPU; Operações lógicas e aritméticas Saltos, laços e procedimentos * * Instruções Assembly adc - adicionar dois operandos mais o carry e coloca o resultado no primeiro. ex add ax,bx add - somar dois operandos e coloca o resultado no primeiro. Ex. add ax,bx and - E lógico bit a bit, coloca o resultado no primeiro operando. Ex. and ax,FFFF cld - zera o flag de direção e segue em ordem crescente. cli - inibe interrupções. call - chama uma subrotina. Ex. call le_num cmp - compara dois operandos. Não altera o resultado dos operandos (subtrai e joga fora o resultado). Ex. cmp ax,bx dec - decrementa de '1' um registrador. Ex. dec ax div - divide dois operandos. Coloca o quociente em dl e o resto em dh. inc - incrementa de '1' um registrador. Ex. inc ax int - chama uma interrupção do S.O. Ex. int 21 As instruções em linguagem Assembly no programa fonte devem obrigatoriamente serem escritas por uma linha no formato: [label:] [operação] [operandos] [;comentários] * * Instruções Assembly jc - desvia se ocorreu carry. Ex. jc fim obs.: fim é um label je - desvia se resultado igual a zero. Ex. je fim jmp - desvio incondicional. Ex. jmp fim jl - desvia se resultado é menor. Ex. jl fim jle - desvia se resultado é menor ou igual. Ex. jle fim jg - desvia se resultado é maior. Ex. jg fim jge - desvia se resultado é maior ou igual. Ex. jge fim jz - desvia se resultado igual a zero. Ex. jz fim jne - desvia se for diferente. Ex. jne fim jnl - desvia se resultado maior ou igual. Ex. jnl fim * * Instruções Assembly jng - desvia se resultado menor ou igual. Ex. jng fim jnz - desvia se resultado não for zero. Ex. jnz fim lahf - carrega flags no ah lea– Carrega endereço efetivo loop - repete um laço cx vezes mov - move dados entre registradores. ex mov ax,bx mul - multiplica AX * operando. Coloca o resultado em DX:AX. Ex. mul bx neg - troca o sinal nop – nenhuma operação not - inverte os bits offset - atribui a um registrador o endereço de memória de uma instrução. Ex. mov di,offset string * * Instruções Assembly or - ou lógico bit a bit. Coloca o resultado no primeiro operando. Ex. : or ax,ax pop - retira o operando da pilha. Ex. pop ax popf - retira os flags da pilha. Ex. popf push - coloca o operando na pilha. Ex. push ax pushf - coloca os flags na pilha. Ex. pushf ret n - retorna para a próxima linha da chamada. O parâmetro n determina o número de bytes a serem desempilhados no retorno além do endereço de retorno. Ex. ret ou ret 4. rcl - rotaciona para a esquerda com carry. rcr - rotaciona para a direita com carry. rol - rotaciona para a esquerda. Ex. rol ax,cx rol ax,1 * * Instruções Assembly ror - rotaciona para a direita. Ex. ror ax,cx ror ax,1 sahf - seta flags à partir do ah sbb - subtrai dois operandos e o carry colocando o resultado no primeiro. Ex. sub ax,bx shl - deslocamento para a esquerda, colocando o bit deslocado no carry e insere zero. shr - deslocamento para a direita, colocando o bit deslocado no carry e insere zero. std - seta o flag de direção em ordem decrescente. sub - subtrai dois operandos colocando o resultado no primeiro. Ex. sub ax,bx xor - ou exclusivo bit a bit, coloca o resultado no primeiro operando. Ex. xor ax,ax * * Instruções Assembly Exercícios: 1 – Escrever um programa para gerar o complemento de 2 de AL 2 – Escrever um programa que determine se existe um byte 0 em AL ou BL ou CL ou DL. Sinalize com AH = 1 caso isto ocorra. 3 –Escrever um programa para determinar o maior valor entre AL, BL, CL e DL e escreve-lo em AH. 4 – Escrever um programa para converter um byte em AL em seu ASCII e escreve-lo na tela 5 –Escreva um programa para ler um dígito hexadecimal de A a F (maiúsculo) e exibi-lo em decimal na próxima linha. Utilize mensagens convenientes. Exemplo: Entre um digito hexa: D O seu valor decimal vale: 14 * * Complemento a 2 Complemento a 2: regra prática Considere X = 0000 1000, o complemento a 2 de X será: -X = 1111 1000 * * Conversão ASCII Algoritmo Considere NH um número hexadecimal de dois dígitos, com valores entre 00 e FFH. Na conversão para ASCII, os dois dígitos são separados e cada dígito é convertido separadamente para o seu respectivo codigo ASCII. O algoritmo a seguir exemplifica a conversão para o número A8H: separa-se o número A8H de dois dígitos. 0AH 08H. (Observe que ambos dígitos ocupam a parte menos significativa do byte). converte-se cada número para o seu respectivo código ASCII. 0AH é convertido para 41H (0A > 09 => 0A+37 = 41) 08H é convertido para 38H (08 ≤ 09 => 08+30 = 38 ) * * Tabela ASCII * * TABELAS DE EQUIVALÊNCIA Cada uma das partes numa linha de código assembly é conhecida como token: MOV AX,Var - Aqui temos três tokens: Instrução MOV, operador AX e operador VAR. O montador lê cada um dos tokens e procurar a equivalência em código de máquina em tabelas correspondentes, seja de palavras reservadas, tabela de códigos de operação, tabela de símbolos, tabela de literais, onde o significado dos mnemônicos e os endereços dos símbolos que usamos serão encontrados. O montador lê MOV e encontra na tabela de códigos de operação o seu equivalente na linguagem de máquina. Lê AX e encontra-o na tabela correspondente como sendo um registrador. O processo para Var é um pouco diferenciado, o montador verifica que ela não é uma palavra reservada, então procura na tabela de símbolos, lá encontrando-a ele designa o endereço correspondente, mas se não encontrou ele, insere na tabela para que ela possa receber um endereço. * * Programação Assembler É importante incluir as seguintes diretivas de montador: .MODEL - Define o modelo de memória usado no programa Modelos de memória possíveis: Ex.: .MODEL small Tiny: um segmento de 64k para acomodar código, pilha de dados e programa (usados para programas .com) Small: Todo código em 1 segmento, enquanto que outros dados estarão em outro; Compact: código não > que 64k mas dados podem usar mais de um segmento Large: Tanto programa, quanto dados podem ser > 64k Huge: semelhante ao Large, mas permite criação de tabelas e matrizes de dados maiores que 64k; Obs.: para a grande maioria das aplicações o small é suficiente; .CODE - Define as instruções do programa, relacionado ao segmento de código .DATA – Reserva uma área de dados para o programa .STACK - Reserva espaço de memória para as instruções de programa na pilha DB – Define Byte – Define um valor na posição de memória indicada. Ex: Byte1 DB 01H, Msg DB ‘Mensagem” END - Finaliza um programa assembly * * Interrupções Interrupção por Hardware Interrupção por Exceção Interrupção por Software * * Interrupções por Software Programas em assembly podem usar serviços do SO para realizar E/S. Essas funções são chamadas pela interrupção INT 21h Os parâmetros dessa subrotina são passados pelos registradores AH, AL, DL; AH determina qual a função esta sendo selecionada. Exemplos: AH Função 1 Entrada de teclado - espera uma caractere ser digitado, mostra-o na tela e guarda seu ASCII em AL; 8 Entrada de teclado sem eco - espera a digitação e guarda seu ASCII em AL 2 Saída na tela - mostra na tela os caracteres (ASCII) armazenados em DL: 9 Saída de string na tela - mostra o string apontado por DS:DX (o ultimo caractere deve ser $) 4Ch retorno ao SO. Sai do programa; * * Exemplo de Programa Assembly ; *******Exemplo de uma estrutura de programa assembly ********* TITLE nome_do_programa .MODEL SMALL .STACK 100h .DATA ; ;definição dos dados: variáveis e constantes ; .CODE EXEMPLO PROC ; ;seqüência de instruções ; EXEMPLO ENDP ; ;segue outras procedures ; END EXEMPLO Obs: na primeira linha tem-se a diretiva TITLE seguida do nome do programa; na última linha tem-se a diretiva END, seguida do nome da procedure principal; se não houver definição de procedure, usa-se apenas END. * * Programação Assembler ; multi-segment executable file template. data segment ; add your data here! pkey db "press any key...$" ends stack segment dw 128 dup(0) ends code segment start: ; set segment registers: mov ax, data mov ds, ax mov es, ax ; add your code here lea dx, pkey mov ah, 9 int 21h ; output string at ds:dx ; wait for any key.... mov ah, 1 int 21h mov ax, 4c00h ; exit to operating system. int 21h ends end start ; set entry point and stop the assembler. * * Tela Inicial EMU8086 * * Tela Inicial EMU8086 * * Simulador EMU8086 * * Exemplo1.asm imprime “R” na tela .model small .stack .code mov ah,2h ;Prepara função 2 (imprime caracter na tela) da int 21 mov dl,52h ; mov dl, ‘R’ - move o valor 52h para o registrador dl ;(é o valor ASCII do caractere “R”) int 21h ;interrupção 21h: Mostra “R” na tela mov ah,4ch ;função 4ch, sai para o sistema operacional int 21h ;interrupção 21h end ;finaliza o programa * * * Imprime nome .model small .stack .code mov dl,'R' ; move o valor R para o registrador dl call print_caracter; imprime caracter mov dl, 'e' ; move o valor e para o registrador dl call print_caracter; imprime caracter mov dl, 'm' ; move o valor ‘m. para o registrador dl call print_caracter; imprime caracter mov dl,'y' ;move o valor y para o registrador dl call print_caracter; imprime caracter Jmp fim Print_caracter proc mov ah,2h ;função 2h, imprime caracter int 21h ;imprime o caracter que está em dl ret ;retorna o controle ao procedimento que chamou Print_caracter endp Fim: mov ah,4ch ;função 4ch, sai para o sistema operacional int 21h ;interrupção 21h end ;finaliza o programa * * Programa Imprime String Use qualquer editor para criar o programa fonte. Entre com as seguintes linhas: Use ; para fazer comentários .MODEL small .STACK 100h ;reserva uma área de pilha, embora não seja usada neste exemplo .DATA mensagem1 DB 'Meu primeiro programa funcionou!!',13,10,'$' .CODE mov ax,data mov ds,ax ;seta DS para apontar para o segmento de dados lea dx,mensagem1 ;aponta para “Meu primeiro programa funcionou" mov ah,9 ;interrupção do SO para imprimir a string int 21h ;mostra "Meu primeiro programa funcionou!!" mov ah,4ch ;Interrupção para terminar o programa int 21h ;termina o programa END Este programa assembly imprime a string da área de dados na tela. * * Exemplo4.asm Este programa mostra os caracteres ABCDEFGHIJ na tela. .model small .stack .code PRINT_A_J PROC MOV DL,'A' ;move o character A para o registrador DL MOV CX,10 ;move o valor decimal 10 para o registrador CX ;este valor é usado para fazer laço com 10 interações PRINT_LOOP: CALL WRITE_CHAR ;Imprime o caracter em DL INC DL ;Incrementa o valor do registrador DL LOOP PRINT_LOOP ;Laço para imprimir 10 caracteres MOV AH,4Ch ;Função 4Ch, para sair ao DOS INT 21h ;Interrupção 21h PRINT_A_J ENDP ;Finaliza o procedimento WRITE_CHAR PROC MOV AH,2h ;Função 2h, imprime caracter INT 21h ;Imprime o caracter que está em DL RET ;Retorna o controle ao procedimento que chamou WRITE_CHAR ENDP ;Finaliza o procedimento END PRINT_A_J ;Finaliza o programa * * Exemplo5.asm Imprime Alfabeto Maiúsculo e Minúsculo ; outro modo de programa .model small .stack .data mensagem1 DB 13,10,'$' .code Title PRINT_A_J MOV DL,'A' ;move o character A para o registrador DL MOV CX,23 ;move o valor decimal 10 para o registrador CX CALL PRINT_LOOP mov ax,data mov ds,ax ;seta DS para apontar para o segmento de dados lea dx,mensagem1 ;aponta para “Meu primeiro programa funcionou" mov ah,9 ;interrupção do SO para imprimir a string int 21h MOV DL, ‘a’ MOV CX,23 ;move o valor decimal 10 para o registrador CX CALL PRINT_LOOP MOV AH,4Ch ;Função 4Ch, para sair ao DOS INT 21h ;Interrupção 21h ;Finaliza o procedimento ;este valor é usado para fazer laço com 10 interações PRINT_LOOP: CALL WRITE_CHAR ;Imprime o caracter em DL INC DL ;Incrementa o valor do registrador DL LOOP PRINT_LOOP ;Laço para imprimir 10 caracteres RET WRITE_CHAR: MOV AH,2h ;Função 2h, imprime caracter INT 21h ;Imprime o caracter que está em DL RET ;Retorna o controle ao procedimento que chamou END ;Finaliza o programa * * Exemplo5.asm Este programa mostra na tela o valor dos 256 caracteres do código ASCII. .model small .stack .code PRINT_ASCII PROC MOV DL,00h ;move o valor 00h para o registrador DL MOV CX,255 ;move o valor decimal 255 para o registrador CX ;usado para fazer um laço com 255 interações PRINT_LOOP: CALL WRITE_CHAR ;Chama o procedimento que imprime INC DL ;Incrementa o valor do registrador DL LOOP PRINT_LOOP ;Loop para imprimir 10 caracteres MOV AH,4Ch ;Função 4Ch INT 21h ;Interrupção 21h PRINT_ASCII ENDP ;Finaliza o procedimento WRITE_CHAR PROC MOV AH,2h ;Função 2h para imprimir um caracter INT 21h ;Imprime o caracter que está em DL RET ;Retorna o controle ao procedimento que chamou WRITE_CHAR ENDP ;Finaliza o procedimento END PRINT_ASCII ;Finaliza o programa * * Exemplo6.asm Este programa lê dois caracteres e os imprime na tela. ;nome do programa: one.asm ; .model small .stack .code mov AH,1h ;Função 1 do DOS int 21h ;lê caracter e retorna código ASCII ao registrador AL mov DL,AL ;move o código ASCII para o registrador DL sub DL,30h ;subtrai de 30h para converter a um dígito de 0 a 9 cmp DL,9h ;compara se o dígito está entre 0 e 9 jle digit1 ;se verdadeiro obtém o primeiro número (4 bits) sub DL,7h ;se falso, subtrai de 7h para converter a uma letra A-F digit1: mov CL,4h ;prepara para multiplicar por 16 shl DL,CL ;multiplica para converter dentro dos 4 bits mais altos int 21h ;obtém o próximo caracter sub AL,30h ;repete a operação de conversão cmp AL,9h ;compara o valor 9h com o conteúdo do registrador AL jle digit2 ;se verdadeiro, obtém o segundo dígito sub AL,7h ;se falso, subtrai de 7h digit2: add DL,AL ;adiciona o segundo dígito mov AH,4Ch ;função 4Ch do DOS (exit) Int 21h ;interrupção 21h End ;finaliza o programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Compartilhar