Você está na página 1de 6

Resumo Teórico 11

Endereçamento
Henrique C. Oliveira1
1
Instituto de Matemática e Computação – Universidade Federal de Itajubá (UNIFEI)
Caixa Postal 37.500-903 – Itajubá – MG – Brasil
henriquecastro@unifei.edu.br

Abstract. Most of the instructions have operands, so you need some way to
specify where they are. This subject, which will be covered in this summary, is
called addressing.

Resumo. Grande parte das instruções tem operandos, portanto, é necessário


algum modo de especificar onde eles estão. Esse assunto, que será discorrido
nesse resumo, é denominado endereçamento. [Tanenbaum et al. 2012]

1. Modos de endereçamento
Até aqui, demos pouca atenção ao modo como os bits de um campo de endereço são
interpretados para achar o operando. Agora, chegou a hora de investigar esse assunto,
denominado modos de endereçamento. Como veremos, existem muitas formas de fazer
isso.

2. Endereçamento imediato
O modo mais simples de uma instrução especificar um operando é a parte da instrução ref-
erente ao endereço conter o operando de fato em vez de um endereço ou outra informação
que descreva onde ele está. O endereçamento imediato tem a vantagem de não exigir uma
referência extra à memória para buscar o operando.

3. Endereçamento direto
Um método para especificar um operando na memória é dar seu endereço completo. As-
sim como o imediato, o endereçamento direto tem uso restrito: a instrução sempre aces-
sará exatamente a mesma localização de memória. Assim, o endereçamento direto só
pode ser usado para acessar variáveis globais cujos endereços sejam conhecidos no mo-
mento da compilação. Não obstante, muitos programas têm variáveis globais, portanto,
esse modo é muito utilizado.

4. Endereçamento de registrador
Endereçamento de registrador é conceitualmente o mesmo que endereçamento direto,
mas especifica um registrador em vez de uma localização de memória. Muitos compi-
ladores fazem todo o possı́vel para determinar quais variáveis serão acessadas com maior
frequência e as colocam em registradores. Em arquiteturas carregue/armazene, como a
arquitetura ARM do OMAP4430, quase todas as instruções usam apenas esse modo de
endereçamento. A única vez em que esse modo de endereçamento não é usado é quando
um operando é transferido da memória para um registrador ou de um registrador para a
memória.
5. Endereçamento indireto de registrador
Nesse modo, o operando que está sendo especificado vem da memória ou vai para ela, mas
seu endereço não está ligado à instrução, como no endereçamento direto. Uma grande
vantagem do endereçamento indireto de registrador é que ele pode referenciar a memória
sem pagar o preço de ter um endereço de memória completo na instrução. Além disso,
também pode usar diferentes palavras de memória em diferentes execuções da instrução.
As três primeiras instruções usam o modo registrador para o primeiro operando e o modo
imediato para o segundo operando .
A segunda instrução coloca o endereço de A em R2, não o conteúdo. De modo
semelhante, a terceira instrução coloca em R3 o endereço da primeira palavra logo após
o vetor. Ele usa o modo registrador e o modo indireto de registrador na quarta instrução.
Usa o modo registrador e o modo indireto de registrador na quarta instrução.
Usa o modo registrador e o modo imediato na quinta instrução e o modo regis-
trador duas vezes na sexta instrução. O BLT poderia usar um endereço de memória, mas
provavelmente especifica o endereço para o qual desviar com um deslocamento de 8 bits
em relação à própria instrução BLT. Vale a pena observar que, em teoria, há outro modo
de fazer esse cálculo sem usar endereçamento indireto de registrador.
Um programa que modifica a si mesmo é denominado programa automodificador.
Além do mais, sequer funcionam corretamente em máquinas que têm uma cache dividida
de nı́vel 1 se a cache de instrução não tiver circuitos para fazer escritas retroativas . Por
fim, programas automodificadores também falharão em máquinas com espaços separados
para instrução e dados. De modo geral, essa é uma ideia que chegou e já se foi.

6. Endereçamento indexado
Muitas vezes, é útil poder referenciar palavras de memória cujo deslocamento em relação
a um registrador é conhecido. Vimos alguns exemplos na IJVM, na qual variáveis locais
são referenciadas dando seu deslocamento em relação a LV. Endereçamento indexado é
o nome que se dá ao endereçamento de memória que fornece um registrador mais um
deslocamento constante. O acesso à variável local em IJVM usa um ponteiro para a
memória em um registrador mais um peque-no deslocamento na própria instrução, como
mostra a Figura 4.19.
A em um registrador, o endereço de B em um segundo registrador, e então per-
corrê-los juntos no mesmo passo, semelhante ao que fizemos na Figura 5.17. Um reg-
istrador, R2, e uma constante, o endereço de A, são somados e usados para referenciar a
memória. A soma dessas duas quantidades vai para a memória, mas não é armazenada
em nenhum registrador visı́vel ao usuário. A notação significa que o destino usa o modo
registrador com R4, ao passo que o registrador e a origem usam o modo indexado, sendo
A o deslocamento e R2 o registrador.
Se A tiver o valor, por exemplo, 124.300, a instrução de máquina para isso
provavelmente é parecida com a mostrada na Figura 5.19. Na primeira vez que o laço
é percorrido, R2 é 0 , portanto, a palavra de memória endereçada é A0, no endereço
124.300. Na próxima vez que o laço é percorrido, R2 é 4, portanto, a palavra de memória
endereçada é A1, em 124.304, e assim por diante. Como tı́nhamos prometido, nesse caso
o deslocamento na instrução em si é o ponteiro de memória e o valor no registrador é um
inteiro pequeno, que é incrementado durante o cálculo.

7. Endereçamento de base indexado


Algumas máquinas têm um modo de endereçamento no qual o endereço de memória é
calculado somando dois registradores mais um deslocamento . Esse modo teria sido útil
aqui. Fora do laço pode-rı́amos ter posto o endereço de A em R5 e o endereço de B em
R6. O ideal seria que houvesse um modo de endereçamento para endereçar indiretamente
a soma de dois regis-tradores sem nenhum deslocamento. Como alternativa, até mesmo
uma instrução com um deslocamento de 8 bits teria sido uma melhoria em relação ao
código original, já que poderı́amos ajustar ambos os deslocamentos para 0.

8. Endereçamento de pilha
8.1. Notação polonesa invertida
A forma com o operador após os operandos é denominada pós-fixa ou notação polonesa
invertida, que deve seu nome ao lógico polonês J. Lukasiewicz , pesquisador das pro-
priedades dessa notação. A notação polonesa invertida tem diversas vantagens sobre a
notação infixa para expressar fórmulas algébri-cas. Primeiro, qualquer fórmula pode ser
expressa sem parênteses. A notação polonesa invertida elimina esse inconveniente.
Existem diversos algoritmos para converter fórmulas infixas em notação polonesa
invertida. Para marcar as extremidades de uma fórmula, vamos inserir o sı́mbolo após
o último sı́mbolo e antes do pri-meiro sı́mbolo. Cada sı́mbolo na fórmula é representado
por um vagão ferroviário. Quando cada vagão chega ao desvio, tem de parar um pouco
antes e perguntar se deve ir dire-to para Belo Horizonte ou desviar a rota para o Rio.
Vagões que contêm todos os outros sı́mbolos têm de perguntar qual é o conteúdo
do vagão mais próximo na linha que vai para o Rio antes de entrar no desvio. Os dados
da Figura 5.21 mostram o que acontece, dependendo do conteúdo do próximo vagão na
linha para o Rio e do vagão que está parado no desvio. Note que a linha do Rio está
sendo usada como uma pilha, sendo que o direcionamento de um vagão para o Rio é uma
operação de passar para a pilha, e fazer o vagão que já está na linha do Rio retornar e
enviá-lo para Belo Horizonte é uma operação de tirar da pilha. A ordem das variáveis é a
mesma na notação infixa e na notação polonesa invertida.
Na notação polonesa invertida, eles aparecem na ordem em que serão realmente
executados durante a avaliação da expressão. A Figura 5.22 dá diversos exemplos de
fórmulas infixas e suas equivalentes em notação polonesa invertida.

8.2. Avaliação de fórmulas em notação polonesa invertida


A notação polonesa invertida é a ideal para avaliar fórmulas em um computador com uma
pilha. O algoritmo para avaliar uma fórmula em notação polonesa invertida é simples.
Examine a cadeia da notação da esquerda para a direita. Quando encontrar um operando,
passe-o para a pilha.
Quando encontrar um operador, execute a instrução correspondente. Esse ponto
é importante para a divisão , visto que a ordem dos operandos é significativa . Se for
uma constante ou variável, pro-duza uma instrução para passá-lo para a pilha. Se for um
operador, produza uma instrução para efetuar a operação.
9. Modos de endereçamento para instruções de desvio
Instruções de desvio também precisam de modos de endereçamento para especificar o
endereço de destino. O endereçamento direto é, sem dúvida, uma possibilidade, bas-
tando incluir o endereço de destino completo na instrução. O endereçamento indireto
de registrador permite que o programa calcule o endereço de destino, coloque-o em um
registrador e então vá até lá.
Esse modo dá a maior flexibilidade, já que o endereço de destino é calculado em
tempo de execução. Nesse modo, o deslocamento na própria instrução é adicionado ao
contador de programa para obter o endereço de destino.

10. Ortogonalidade de opcodes e modos de endereçamento


Como exemplo de um projeto limpo para uma máquina de três endereços, considere os
formatos de instru-ção de 32 bits da Figura 5.24. O campo de 8 bits não utilizado da
extremidade pode ser usado ainda para diferenciar a instrução. Além disso, se o bit 23
estiver marcado, o formato 2 é usado e o segundo operando não é mais um registrador, mas
uma constante imediata de 13 bits, com sinal. As instruções LOAD e STORE também
podem usar esse formato para referenciar memória no modo indexado.
Por exemplo, um opcode poderia ser designado a cada desvio , chamada de pro-
cedimento etc., deixando 24 bits para um deslocamento em relação ao PC. Agora, con-
sidere um projeto para uma máquina de dois endereços que pode usar uma palavra de
memória para qualquer um dos operandos. Essa máquina pode somar uma palavra de
memória a um registrador, somar um registrador a uma palavra de memória, somar um
registrador a outro ou somar uma palavra de memória a outra. Hoje, os acessos à memória
são relativamente caros, portanto, esse projeto ainda não é popular, mas, se os progressos
na tecnologia de cache ou memória tornarem os acessos à memória baratos no futuro,
produzir código para esse projeto será particularmente fácil e eficiente.
Nesse projeto temos, mais uma vez, um opcode de 8 bits, mas agora temos 12 bits
para especificar a origem e 12 bits para especificar o destino. Para cada operando, 3 bits
dão o modo, 5 bits dão o registrador e 4 bits dão o deslocamento. Com 3 bits de modo
podemos suportar modos imediato, direto, registrador, indireto de registra-dor, indexado
e de pilha, e ainda sobra espaço para dois modos futuros. O único problema é que, para
endereçamento direto, precisamos de mais bits para o endereço.
Também poderı́amos usar um de dois modos de endereçamento disponı́veis em
lugar de um modo indexado com um deslocamento de 32 bits após a instrução. Assim, na
pior das hipóteses, por exemplo, um ADD de memória para memória cujos dois operan-
dos fossem endereçados diretamente, ou utilizassem uma forma indexada longa, teria 96
bits de comprimento e usaria três ciclos de barramento . Por outro lado, a maioria dos
projetos RISC exigiria no mı́nimo 96 bits, talvez mais, para somar uma palavra qualquer
na memória com outra, e usaria no mı́nimo quatro ciclos de barramento, dependendo de
como os operandos fossem endereçados. Por outro lado, para variáveis além de 16, temos
de ir a deslocamentos de 32 bits.
Uma opção seria outro formato com um único deslocamento de 8 bits em vez de
dois de 4 bits, mais uma regra informando que a origem ou o destino poderiam usá-lo,
mas não ambos.
11. Modos de endereçamento do Core i7
Os modos de endereçamento do Core i7 são muito irregulares e diferentes dependendo
de determinada instrução estar em modo de 16, 32 ou 64 bits. Os modos suportados
são imediato, direto, registrador, indireto de registrador, indexado e um especial para
endereçar elementos de vetores. O problema é que nem todos os modos se aplicam a
todas as instruções e nem todos os registradores podem ser usados em todos os modos. O
byte MODE da Figura 5.13 controla os modos de endereçamento.
As colunas 01 e 10 envolvem modos nos quais um registrador é somado a um
deslocamento de 8 ou 32 bits que vem após a instrução. Se for selecionado um desloca-
mento de 8 bits, antes de ser somado ele é estendido em sinal para 32 bits. Por exemplo,
uma instrução ADD com R/M = 011, MOD = 01 e um deslocamento de 6 calcula a soma
EBX + 6 e lê a palavra de memória naquele endereço para um dos operandos. Por ex-
emplo, não há nenhum modo de endereçar indiretamente por EBP e nenhum modo de ter
deslocamento em relação a ESP.
Os modos SIB são úteis para acessar elementos de vetores. De modo geral, o
EBP é usado para apontar para a base do quadro de pilha que contém as variáveis locais
e vetores, como mostra a Figura 5.27. Para acessar a , ele usaria um modo SIB cujo
endereço de operando fosse a soma de 4 EAX, EBP e 8. Essa instrução poderia armazenar
em a com uma única instrução.
Não há dúvida de que essa instrução, usada de modo adequado, eco-nomiza alguns
ciclos. A frequência com que é usada depende do compilador e da aplicação. O problema
é que ela ocupa certa quantidade de área de chip que poderia ter sido usada de um modo
diferente se essa instrução não estivesse presente. Por exemplo, a cache de nı́vel 1 poderia
ser maior, ou o chip poderia ser menor, o que permitiria talvez uma velocidade de clock
ligeiramente mais alta.
Ainda assim, um grande número de descendentes daquele produto agora é usado
principalmente para navegar na Web, portanto, as decisões tomadas há 20 anos podem
estar de todo erradas para as aplicações atuais.

12. Modos de endereçamento da CPU ARM do OMAP4430


No OMAP4430, todas as instruções usam endereçamento imediato ou de modo reg-
istrador, exceto as que endereçam a memória. Para o modo registrador, os 5 bits apenas
informam qual registrador usar. Para o modo imediato, uma constante de 12 bits fornece
os dados. Não há nenhum outro modo presente para as instruções aritméticas, lógicas e
similares. Esse terceiro modo, chamado endereçamento relativo ao PC, é útil para carregar
constantes do programa que estão armazenadas com o código do programa.

13. Modos de endereçamento da AVR do ATmega168


Registradores podem ser usados como origens e destinos. O segundo é o modo imediato,
em que um valor imediato de 8 bits sem sinal pode ser codificado em uma instrução. Para
instruções de 16 bits, o endereço direto é limitado a 7 bits . A arquitetura AVR também
define uma instrução de 32 bits, que acomoda um endereço direto de 16 bits, admitindo
até 64 KB de memória.
Como registradores normais têm 8 bits de largura, instruções de carga e armazena-
mento usam pares de registradores para expressar um endereço de 16 bits. Para carregar
um endereço no registrador X, por exemplo, o programa teria de carregar um valor de 8
bits nos registradores R26 e R27, usando duas instruções de carga.

14. Discussão de modos de endereçamento


Neste ponto, já estudamos diversos modos de endereçamento. Os usados pelo Core i7,
OMAP4430 e ATmega168 estão resumidos na Figura 5.28. Visto que, hoje, a maioria
dos códigos escritos nesse nı́vel será gerada por compiladores , o aspecto mais impor-
tante dos modos de endereçamento de uma arquitetura é que haja poucas opções e que
elas sejam claras, com custos que possam ser calculados imediatamente. Em geral, isso
significa que uma máquina deve adotar uma posição extrema: ou deve oferecer todas as
opções possı́veis ou apenas uma. Na prática, ter os modos imediato, direto, registrador
e indexado costuma ser suficiente para quase todas as aplicações. Além disso, todo reg-
istrador deve ser usável onde quer que haja necessidade de um registrador. Modos de
endereçamento mais complicados conseguem reduzir o número de instruções, porém, à
custa da introdução de sequências de operações que não podem ser facilmente executadas
em paralelo com outras operações sequenciais.

References
Tanenbaum, A. S., Austin, T., Cossio, M. L. T., Giesen, L. F., Araya, G., Pérez-Cotapos,
M. L. S., VERGARA, R. L., Manca, M., Tohme, R. A., Holmberg, S. D., Bressmann,
T., Lirio, D. R., Román, J. S., Solı́s, R. G., Thakur, S., Rao, S. N., Modelado, E. L.,
La, A. D. E., Durante, C., Tradición, U. N. A., En, M., Espejo, E. L., Fuentes, D. E.
L. A. S., Yucatán, U. A. D., Lenin, C. M., Cian, L. F., Douglas, M. J., Plata, L., and
Héritier, F. (2012). Structured Computer Organization (6th Edition), volume XXXIII.

Você também pode gostar