EA-869 - Dúvidas Frequentes
Capítulo V
O que é uma pseudo-instrução?
De acordo com a introdução da seção V.3 do livro-texto,
"a arquitetura dos processadores não possui facilidades para passagem de parâmetros,
ficando a cargo do programador esta tarefa". Por que ao escrevermos um programa
em linguagem de alto nível nunca precisamos nos preocupar com este detalhe?
Qual foi o mecanismo utilizado para o endereço de retorno nos
programas-exemplos da seção V.4.2 do Capítulo?
Por que o seguinte código (adaptado da Fig. 5.11 do
livro-texto) com passagem
de parâmetros junto à subrotina não é relocável? Qual modo
de endereçamento poderia ser utilizado para torná-lo relocável?
Endereço |
Conteúdo |
200 |
reservado para primeiro parâmetro |
201 |
reservado para segundo parâmetro |
202 |
reservado para terceiro parâmetro |
203 |
Primeira instrução da subrotina |
204 |
... |
220 |
ADD 200,201 |
221 |
... |
230 |
MOVE R1,203 |
231 |
RTS |
.
Sabendo que a convenção de passagem de parâmetros é por área da memória
associada à subrotina (seção V.4.2.2 do Capítulo), é possível implementar um código
relocável?
A primeira instrução MOVE #50,S na Fig. 5.13 está
correta?
A passagem de parâmetros por área comum de parâmetros
facilita a implementação de códigos reentrantes? Justifique.
Podemos considerar a passagem de parâmetros por pilha uma
variante da passagem de parâmetros por área comum de parâmetros? Justifique.
A instrução PUSH R6 na Fig. 5.17 está
correta?
O que é uma pseudo-instrução?
Uma pseudo-instrução é uma diretiva que não pertence ao repertório de
instruções de um processador, mas leva um montador (a ser visto no
Capítulo IX) a tomar certas ações em relação ao programa. Por exemplo,
reservar espaço na Unidade de Memória para dados (p. ex., DS),
atribuir um valor a um endereço da Unidade de memória (p. ex., DW)
e controlar o endereço onde o programa deve ser carregado (p. ex.,
ORG).
De acordo com a introdução da seção V.3 do livro-texto,
"a arquitetura dos processadores não possui facilidades para passagem de parâmetros,
ficando a cargo do programador esta tarefa". Por que ao escrevermos um programa
em linguagem de alto nível nunca precisamos nos preocupar com este detalhe?
Porque, como vimos no Capítulo I do livro-texto, existem programas
como tradutores e compiladores que "convertem" programas em linguagem
de alto nível para instruções de máquina. São eles quem se preocupam
com os mecanismos de armazenamento de endereços de retorno, de passagem
de parâmetros, a preservação dos conteúdos dos registradores
ao desviar de uma subrotina a outra e, ainda, com a consistência
entre os códigos dos programas que chamam e os códigos
dos programas "chamados".
Dependendo de como as subrotinas
são traduzidas para instruções de
máquinas, limitações podem se refletir
no uso de subrotinas em linguagem de alto nível. Por exemplo, se
o compilador opta pelo mecanismo de armazenar o endereço de retorno
junto à subrotina durante a "conversão", a linguagem de alto nível
certamente não suportará chamadas recursivas. Outro exemplo,
se o compilador optar pela estratégia de passagem de parâmetros por
registradores da UCP, a quantidade de parâmetros que uma subrotina
em linguagem de alto nível pode ter será provavelmente limitada.
Qual foi o mecanismo utilizado para o endereço de retorno nos
programas-exemplos da seção V.4.2 do Capítulo?
Observe que em todos os exemplos (Fig. 5.7, 5.9, 5.11, 5.14, 5.16 e 5.17)
foi utilizada a instrução RTS para retornar ao programa
principal, ou seja, o mecanismo utilizado foi armazenamento de
endereço de retorno através de uma pilha.
Note ainda que em todos programas principais dos exemplos foi
incluída a instrução
MOVE #50,SP
para inicializar o topo da pilha (SP) com o valor 50 (endereço onde inicia
a pilha). Recapitulando os conceitos do Capítulo IV,
foi utilizado na instrução o modo de endereçamento imediato para especificar
o primeiro operando e o modo de endereçamento direto por registrador para
referenciar o segundo operando.
Por que o seguinte código (adaptado da Fig. 5.11 do
livro-texto) com passagem
de parâmetros junto à subrotina não é relocável? Qual modo
de endereçamento poderia ser utilizado para torná-lo relocável?
Endereço |
Conteúdo |
200 |
reservado para primeiro parâmetro |
201 |
reservado para segundo parâmetro |
202 |
reservado para terceiro parâmetro |
203 |
Primeira instrução da subrotina |
204 |
... |
220 |
ADD 200,201 |
221 |
... |
230 |
MOVE R1,203 |
231 |
RTS |
Um código relocável é um código cuja execução independe da
posição onde ele está localizado na Unidade de Memória.
Observe que nas instruções ADD e MOVE foi utilizado
o modo de endereçamento absoluto direto. Exceto o campo que contém
R1, os campos de endereço
contêm endereços efetivos dos operandos na Unidade de Memória. Se
carregarmos a subrotina num outro endereço, como no endereço 500,
deveremos alterar esses campos de endereço
(no caso, ADD 500,501 e
MOVE R1,503)
para que a subrotina execute corretamente.
Podemos, entretanto, reescrever a subrotina com uso do
modo de endereçamento relativo para que o código torne-se
relocável:
Endereço |
Conteúdo |
200 |
reservado para primeiro parâmetro |
201 |
reservado para segundo parâmetro |
202 |
reservado para terceiro parâmetro |
203 |
Primeira instrução da subrotina |
204 |
... |
220 |
ADD -21(PC),-20(PC) |
221 |
... |
230 |
MOVE R1,-28(PC) |
231 |
RTS |
Note que neste novo trecho de código os endereços dos operandos
e do resultado são determinados em função do (PC), independentemente
do endereço em que a subrotina foi carregada.
Sabendo que a convenção de passagem de parâmetros é por área da memória
associada à subrotina (seção V.4.2.2 do Capítulo), é possível implementar um código
relocável?
Para ilustrar utilizaremos a Fig. 5.12 e suporemos que o programa principal, os dados
e a subrotina formem um corpo único.
Observe que o modo de endereçamento utilizado na Fig. 5.12 foi, com exceção da primeira
instrução, absoluto direto. Se relocarmos o código,
precisaremos alterar o conteúdo dos
campos de endereço das instruções MOVE e CALL para que elas executem corretamente.
Vimos que uma forma de tornar um código relocável seria utilizar
o modo de endereçamento relativo
- definir o endereço efetivo em função do (PC).
Podemos substituir
CALL SUB
por
CALL d(PC),
onde d = endereço inicial da subrotina - endereço da
instrução CALL - 1(palavra).
De forma análoga, poderemos substituir os endereços DADO1,
DADO2 e RESUT.
Vejamos agora os endereços DIN1, DIN2 e RES.
Eles têm posições bem definidas com base em SUB, o que nos sugere a utilizar
o modo de endereçamento baseado, como mostra o seguinte trecho de código:
MOVE #SUB,R1 |
MOVE d1(PC),-3(R1) |
MOVE d2(PC),-2(R1) |
CALL d(PC) |
MOVE d3(PC),-1(R1) |
Entretanto, este trecho de código não é ainda relocável por causa da instrução
MOVE #SUB,R1.
A primeira instrução MOVE #50,S na Fig. 5.13 está
correta?
Não. Substitua SP no lugar de S.
SP (Stack Pointer)
denota o
registrador que aponta para o topo da pilha.
A passagem de parâmetros por área comum de parâmetros
facilita a implementação de códigos reentrantes? Justifique.
Sim, porque a área de dados é separada do corpo do programa.
Um código reentrante é um código que não utiliza armazenagem temporária
em seu próprio corpo, podendo ser interrompido, reusado em um novo contexto e
retomado sem afetar o fluxo de controle do contexto anterior.
Um sistema que suporta reentrância deve ser provido de
mecanismos, normalmente programas, que permitam preservar os conteúdos dos
registradores de uso geral e
de uso específico (p. ex., SP, PC e Condition Code Register) e das palavras da Memória utilizadas
em cada contexto. Uma estratégia é alocar um espaço de memória a cada contexto,
como mostra a figura (A), para
- salvar os conteúdos dos registradores antes de utilizá-los no novo contexto; e
- armazenar os dados adicionais armazenados na Unidade de Memória.
Sempre antes de retornar ao contexto anterior o sistema deve restaurar os conteúdos
dos registradores e os conteúdos dos endereços da Unidade de Memória adicionalmente
utilizados.
Para reduzir número de transferências entre os endereços da Unidade de Memória, faz-se
comumente uso de modo de endereçamento baseado. Ao invés de utilizar os mesmos
endereços da Unidade de Memória para todos os contextos, salvando e restaurando-os em
cada mudança de contexto (figura (A)), os programas só utilizarão
palavras da Unidade de Memória cujos
endereços são referenciados com base no endereço inicial do espaço de memória
associado a cada contexto. O sistema se responsabilizará
por gerenciar estes endereços iniciais
e carregará corretamente o registrador de base em cada passagem de contexto, como
mostra a figura (B).
Para exemplificar, reescreveremos o código da Fig. 5.16 utilizando
somente o modo de endereçamento baseado e considerando ainda, que o sistema tenha carregado R1 com
o valor 3000 e que os dados estejam organizados
contiguamente na Memória conforme o seguinte esquema:
|
MOVE (R1),SP |
|
................. |
|
MOVE 1(R1),4(R1) |
|
MOVE 2(R1),5(R1) |
|
CALL SUB |
|
MOVE 6(R1),3(R1) |
|
................. |
|
STOP |
|
................. |
SUB: |
................. |
|
MOVE 4(R1),R2 |
|
MOVE 5(R1),R3 |
|
ADD R2,R3 |
|
................. |
|
MOVE R3,6(R1) |
|
RTS |
Observe que o bloco pode corresponder ao bloco de variáveis
locais de um contexto da figura (B), fazendo (RB)=(R1).
Podemos considerar a passagem de parâmetros por pilha uma
variante da passagem de parâmetros por área comum de parâmetros? Justifique.
Sim. Na estratégia de passagem por pilha o programa
principal e a subrotina acessam os parâmetros numa área comum de Memória,
que no caso é organizada em estrutura de pilha. Portanto, podemos
utilizar o modo de endereçamento baseado na Fig. 5.17. para referenciar os
dados da pilha, usando como endereço-base o conteúdo do apontador de pilha (SP).
A instrução PUSH R5 na Fig. 5.17 está
correta?
Não. Substitua-a por PUSH R6.
Last modified: Fri Oct 10 21:42:27 BRA 1997
Sugestões para ting@dca.fee.unicamp.br
Voltar para a página do curso.
Ting