Tutorial do assembler 8086 para principiantes (parte 2) Acesso à Memória Para acessar a memória nós podemos usar estes quarto registros: BX, SI, DI, BP. Combinando estes registros dentro dos símbolos [ ] , podemos obter diferentes locais de memória. As seguintes combinações são suportadas (modos de endereçamento - addressing modes): [BX [BX [BP [BP + + + + SI] DI] SI] DI] [SI] [DI] d16 (somente variável) [BX] [BX [BX [BP [BP + + + + SI DI SI DI [SI [DI [BP [BX + + + + d8] d8] d8] d8] [BX [BX [BP [BP [SI [DI [BP [BX + + + + d16] d16] d16] d16] + + + + SI DI SI DI + + + + d16] d16] d16] d16] + + + + d8] d8] d8] d8] d8 – É um deslocamento com uma constante de 8 bits com sinal (signed) por exemplo: 22, 55h, -1, etc... d16 – É um deslocamento com uma constante de 16 bits com sinal (signed) por exemplo: 300, 5517h, -259, etc... O deslocamento pode ser uma constante ou uma variável (contendo um offset), ou até mesmo ambos. Se existirem vários valores, o assembler vai avaliar todos os valores e calcular um único valor constante. Deslocamentos podem estar dentro ou fora dos símbolos [ ], o assembler gera o mesmo código de máquina das duas maneiras. O deslocamento é um valor com sinal (signed), portanto pode ser tanto positivo quanto negativo. Geralmente o compilador cuida das diferenças entre d8 e d16, e gera o código de máquina apropriado. Por exemplo, vamos assumir que DS = 100, BX = 30, SI = 70. O seguinte modo de endereçamento (addressing mode): [BX + SI] + 25 é calculado pelo processador para o seguinte endereço físico: 100 * 16 + 30 + 70 + 25 = 1725. Por padrão o registro de segmento DS é utilizado de todos os modos exceto aqueles com registro BP, para esses é usado o registro de segmento SS. Usando a tabela abaixo fica mais fácil de lembrar todas as possíveis combinações: * disp = displacement (deslocamento) Você pode formar todas as cominações válidas usando apenas um item de cada coluna ou não utilizar nenhum valor dela. Como você pode ver BX e BP nunca são utilizados juntos. SI e DI também não. Exemplos de modos de endereçamento válidos: [BX+5] , [BX+SI] , [DI+BX-4] O valor contido em um registro de segmento (CS, DS, SS, ES) é chamado segmento, e o valor no registro de propósito geral (BX, SI, DI, BP) é chamado offset (relativo). Quando DS contém o valor 1234h e SI contém o valor 7890h isso também pode ser escrito como 1234:7890. O endereço físico será 1234h * 10h + 7890h = 19BD0h. Se um zero é adicionado à um número decimal este é multiplicado por 10, contudo 10h = 16, logo se zero é adicionado a um valor hexadecimal, este é multiplicado por 16, por exemplo: 7h = 7 70h = 112 Para informar ao compilador qual o tipo de dados, os seguintes prefixos deverão ser usados: byte ptr - para byte. word ptr – para word (palavra - 2 bytes). por exemplo: byte ptr [BX] ou word ptr [BX] ; acessa byte. ; acessa word. O assembler também suporta abreviaçoes dos prefixos: b. - para byte ptr w. - para word ptr Em certos casos o assembler calcula o tipo de dados automaticamente. Instrução MOV Copia o segundo operando (origem) para o primeiro operando (destino). O operando de origem pode ter um valor imediato, registro de propósito geral ou endereço de memória. O operando de destino pode ser um registro de propósito geral ou um endereço de memória. Ambos os operandos têm que ter o mesmo tamanho, que pode ser um byte ou uma word (2 bytes). Estes são os tipos de operandos suportados: MOV REG, memória MOV memória, REG MOV REG, REG MOV memória, constante MOV REG, constante REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP. memória: [BX], [BX+SI+7], variáveis, etc... constantes: 5, -24, 3Fh, 10001101b, etc... Para registros de segmento somente os seguintes tipos de MOV são suportados: MOV SREG, memória MOV memória, SREG MOV REG, SREG MOV SREG, REG SREG: DS, ES, SS, e somente como segundo operando: CS. REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP. memória: [BX], [BX+SI+7], variável, etc... A instrução MOV não pode ser usada para modificar o valor dos registros CS e IP. Este é um pequeno programa que mostra o uso da instrução MOV: ORG 100h 1 segmento. MOV AX, 0B800h MOV DS, AX MOV CL, 'A' MOV CH, 1101_1111b MOV BX, 15Eh MOV [BX], CX RET ; Esta diretiva é necessária para um programa simples .com de ; ; ; ; ; ; ; atribui copia o atribui atribui atribui copia o retorna ao AX o valor hexadecimal de B800h. valor de AX para DS. ao CL o código ASCII de 'A', que é 41h. um valor binário ao CH. 15Eh ao BX. conteúdo de CX para a memória no endereço B800:015E ao sistema operacional. Você pode copiar & colar o programa acima no editor de códigos, e clicar no botão [Compile and Emulate] ou teclar F5 no seu teclado. A janela do emulador deve abrir com este programa carregado, clique no botão [Single Step] e preste atenção nos valores dos registros. O caractere ";" é usado para comentários, qualquer coisa escrita após o simbolo ";" será ignorado pelo compilador. Você deve ver algo parecido com isto quando o programa acabar de rodar: Na verdade o programa escreve diretamente na memória de vídeo, então como pode ver MOV é uma instrução muito poderosa.