52 pág.

Pré-visualização | Página 8 de 11
Figura 13: Formação do endereço físico no 8086/88 para acesso a código. No caso dos endereços de operandos, o microprocessador busca o endereço de início de segmento em qualquer dos registradores de segmento (CS, DS, SS e ES). Já o "offset" dos endereços de operandos pode envolver até 3 componentes: • Base, • Índice, e • Deslocamento A Figura 14 ilustra como o 8086/88 calcula o "offset" e como é formado o endereço físico dos operandos. Os fatores base, índice e deslocamento podem ser contabilizados ou não para o cálculo do "offset" dependendo do modo de endereçamento utilizado pela instrução executada. Uma questão a ser ainda esclarecida é: num acesso a um operando qual dos registradores de segmento deve ser usado para determinar o endereço de início de segmento? De um modo geral vale a seguinte regra: Linguagem Assembly Família Intel última revisão Ago/2007 38 Figura 14: Formação do endereço no 8086/800 (a) para acesso a código, (b) para acesso a operando. • para cesso a código usa-se sempre o registrador CS, • para acesso a dados fora da pilha usa-se normalmente DS , • para acesso a dados na pilha usa-se SS , o conteúdo do registrador BP é usado para compor o endereço efetivo do operando, o registrador de segmento é o SS Existem instruções, no entanto, que utilizam o registrador ES ao invés do registrador DS para acessar dados. As instruções de manipulação de "strings" implicam no uso do registrador ES na formação do endereço efetivo do operando nos acessos de escrita. Desta forma a instrução MOVS transfere o byte ou palavra contida no endereço (DS:SI) para o endereço (ES:DI). De modo semelhante a instrução CMPS compara o byte ou palavra contido no endereço (DS:SI) com o byte ou palavra do endereço (ES:DI). Também a instrução SCAS compara o conteúdo do acumulador (registrador AL ou AX) com o conteúdo do endereço definido por (ES:DI). Linguagem Assembly Família Intel última revisão Ago/2007 39 Além disso, é possível forçar o microprocessador a utilizar no cálculo do endereço efetivo um registrador de segmento diferente do previsto pela regra acima ("default"). Nestes casos a instrução recebe um prefixo que impõe a utilizarão de um registrador de segmento distinto do definido por essas regras. A instrução código instrução clocks 88 9C 00 40 9+EA por exemplo, move o conteúdo da posição de memória, cujo endereço efetivo é dado pelo conteúdo do registrador DS ("default" neste caso) deslocado 4 bits à esquerda, adicionado ao valor do deslocamento, que neste caso é o endereço do primeiro byte do vetor ARRAY, adicionado ainda ao conteúdo do registrador de índice SI, para o registrador BL. Se, ao invés de utilizar o registrador de segmento "default", se deseja utilizar, digamos, o registrador ES, a instrução em Assembly toma a seguinte forma: código instrução clocks 26 88 9C 00 40 9+EA Há casos, no entanto, em que não se pode utilizar outro registrador de segmento diferente do "default". Por exemplo, nos acessos a instrução o registrador CS é sempre utilizado. Da mesma forma, quando se acessa a pilha utilizando o registrador apontador de pilha - SP - necessariamente se utiliza o registrador SS como registrador de segmento. O conteúdo dos registradores de segmento é normalmente definido no início da execução do programa, utilizando instruções apropriadas. Nada impede porém que o conteúdo dos registradores de segmento seja alterado várias vezes ao longo do programa. A grande vantagem do uso destes registradores de segmento é que tanto os códigos como os dados e a pilha podem ser carregados em qualquer região da memória, sem que seja necessário modificar o código objeto. Basta carregar os registradores de segmento de modo adequado. O sistema operacional de um microcomputador pessoal, por exemplo, antes de carregar um programa na memória, verifica qual a região da memória que está disponível naquele momento e carrega o programa da memória de massa naquela região. Antes de passar o controle para o programa carregado, o sistema operacional carrega os registradores de segmento com os valores adequados. Na maioria dos microprocessador de 8 bits, como o 8085, por exemplo, os endereços estão fixos no código objeto. Para se alterar a região de memória onde um programa do 8085 será carregado é necessário alterar o código objeto. Programas que podem ser carregados em qualquer região da memória sem que o código objeto precise ser alterado, são chamados programas relocáveis. Linguagem Assembly Família Intel última revisão Ago/2007 40 7 O Mecanismo de Segmentação e as Instruções de Desvio Evidentemente o mecanismo de segmentação da memória tem implicações sobre o conjunto de instruções do microprocessador. O primeiro aspecto a abordar aqui diz respeito às instruções de desvio: JMP, CALL e RET. Existem dois tipos de desvio: o intra-segmento e o inter-segmento. 7.1 Desvios intra-segmento Numa instrução JMP intra-segmento o endereço para onde o programa deve ser desviado, pertence ao mesmo segmento onde está armazenada a instrução JMP em execução. Neste caso, a instrução deve conter, além do código do JMP, a especificação do novo valor do registrador IP. O seguintes exemplos são esclarecedores: código instrução clocks E9 00 40 15 FF E3 11 FF A7 00 40 18+EA No primeiro exemplo o valor a ser carregado no IP é definido na própria instrução. O valor codificado na instrução neste caso é na realidade a diferença entre o conteúdo atual e o novo conteúdo de IP. O que o microprocessador faz na prática é somar este valor contido na instrução ao conteúdo de IP. Este tipo de desvio é chamado desvio direto. No segundo e terceiro exemplos tem-se desvios indiretos. No segundo caso o conteúdo do registrador BX é copiado no registrador IP. No terceiro exemplo carrega- se em IP a palavra armazenada no endereço de memória especificado na instrução. Em todos os exemplos acima se diz que o desvio é do tipo próximo (NEAR), um sinônimo de desvio intra-segmento. Deve-se distinguir um tipo de instrução de desvio intra-segmento. Quando a diferença entre o endereço que contém a instrução JMP e o endereço de desvio está entre -128 e 127, pode se utilizar o desvio curto (SHORT). Esta situação é muito frequente em pequenos "loops". Neste caso é especificado na instrução o código da instrução JMP e a diferença entre o valor atual e o novo valor do registrador IP expresso em 8 bits. Este tipo de desvio é chamado desvio relativo. Exemplo: Linguagem Assembly Família Intel última revisão Ago/2007 41 código instrução clocks EB 0F 15 Neste caso ao conteúdo de IP é acrescido o valor 0FH. Observe que o código neste caso é mais compacto. código instrução clocks E9 78 01 15 Observe que o primeiro byte do código do JMP é diferente em cada caso. 7.2 Desvios inter-segmento Diz-se que o desvio é do tipo inter-segmento, quando o endereço para onde o programa deve desviar está em outro segmento. Neste caso é preciso especificar na instrução os novos valores para os registradores IP e CS, como nos exemplos abaixo. código Instrução clocks EA 00 30 34 02 15 FF AC 28 00 24+EA No primeiro exemplo têm-se um desvio direto, e no segundo caso um desvio indireto. Diz-se em ambos os casos que o desvio é do