Subrotinas - DCA

Propaganda
EA869
Subrotinas
Faculdade de Engenharia Elétrica e de Computação (FEEC)
Universidade Estadual de Campinas (UNICAMP)
Prof. Levy Boccato
1
Objetivos
 Definir o conceito de subrotina e sua importância na
implementação de código em linguagem de montagem.
 Conhecer as estratégias para a correta preparação de
subrotinas.
 Conhecer de que modo são passados parâmetros à
subrotina.
2
Recordando
 Nas últimas aulas, vimos como um processador pode executar
instruções de forma mais eficiente através da técnica de pipeline.
 Além disso, também conhecemos quais os modos de endereçamento
permitidos em uma instrução.
 Resumidamente, aprendemos como melhorar o desempenho de um
processador no que diz respeito à taxa de execução das instruções, e
como adequar as instruções aos dados que queremos manipular.
Como otimizar a escrita de
um programa Assembly,
principalmente em relação
ao uso da memória?
3
Exemplo
 Considere o exemplo abaixo em linguagem Assembly fictícia, onde o
OP1 é o registrador destino:
MOV R0, #100
MOV R1, (R0)+
MOV R2, (R0)+
ADD R3, R1, R2
MOV (R0), R3
MOV R0, #200
MOV R1, (R0)+
MOV R2, (R0)+
ADD R3, R1, R2
MOV (R0), R3
MOV R0, #300
MOV R1, (R0)+
MOV R2, (R0)+
ADD R3, R1, R2
MOV (R0), R3
O programa faz somas de posições contíguas
da memória e armazena o resultado no
último endereço.
Necessita de 15 linhas de memória.
O que poderíamos
fazer para otimizar
a escrita deste
programa?
4
Exemplo
 Observe que parte do código se repete ao longo do programa.
MOV R0, #100
MOV R1, (R0)+
MOV R2, (R0)+
ADD R3, R1, R2
MOV (R0), R3
MOV R0, #200
MOV R1, (R0)+
MOV R2, (R0)+
ADD R3, R1, R2
MOV (R0), R3
MOV R0, #300
MOV R1, (R0)+
MOV R2, (R0)+
ADD R3, R1, R2
MOV (R0), R3
5
Exemplo
 Observe que parte do código se repete ao longo
Criar um subprograma ou uma subrotina!
MOV R0, #100
MOV R1, (R0)+
MOV R2, (R0)+
ADD R3, R1, R2
MOV (R0), R3
MOV R0, #200
MOV R1, (R0)+
MOV R2, (R0)+
ADD R3, R1, R2
MOV (R0), R3
MOV R0, #300
MOV R1, (R0)+
MOV R2, (R0)+
ADD R3, R1, R2
MOV (R0), R3
O que poderíamos
fazer para resolver
redundância?
do essa
programa.
Label identifica a posição de memória onde se
inicia a subrotina.
SUB:MOV R1, (R0)+
MOV R2, (R0)+
ADD R3, R1, R2
MOV (R0), R3
RTS
Instrução que informa o fim da subrotina.
6
Exemplo
 Observe que parte do código se repete ao longo
Criar um subprograma ou uma subrotina!
PRINC: MOV R0, #100
CALL SUB
MOV R0, #200
CALL SUB
MOV R0, #300
CALL SUB
MOV R0, #200
O que poderíamos
fazer para resolver
redundância?
do essa
programa.
Label identifica a posição de memória onde se
inicia a subrotina.
SUB:MOV R1, (R0)+
MOV R2, (R0)+
ADD R3, R1, R2
Instrução que
chama a subrotina
MOV (R0), R3
RTS
Instrução que informa o fim da subrotina.
MOV R0, #300
7
Exemplo
 Observe que parte do código se repete ao longo
Criar um subprograma ou uma subrotina!
PRINC: MOV R0, #100
CALL SUB
MOV R0, #200
CALL SUB
MOV R0, #300
CALL SUB
O que poderíamos
fazer para resolver
redundância?
do essa
programa.
Label identifica a posição de memória onde se
inicia a subrotina.
SUB:MOV R1, (R0)+
MOV R2, (R0)+
ADD R3, R1, R2
Instrução que
chama a subrotina
MOV (R0), R3
RTS
Instrução que informa o fim da subrotina.
O programa que antes ocupava 15 linhas
de memória, agora necessita apenas de 6.
Além disso, a subrotina poderá ser
aproveitada em outras partes do
programa, tornando o código que
efetivamente é armazenado mais enxuto.
Conceito de
modularização
8
Subrotinas
 Definição:
 Subrotinas permitem que uma mesma sequência de instruções
seja executada em diferentes pontos de um programa, sobre
diferentes conjuntos de dados.
 O fluxo de execução do programa será desviado para a posição
de memória onde a subrotina está armazenada; após a
execução da mesma, o controle deverá ser retornado ao ponto
imediatamente posterior ao da ocorrência do desvio.
9
Subrotinas
 Vantagens:
 Redução de código duplicado em um programa.
 Possibilidade de reutilizar o mesmo código sem grandes alterações em
outros programas.
 Decomposição de problemas grandes em pequenas partes – recurso
bastante comum em linguagens de alto nível.
 Melhorar a interpretação visual de um programa.
 Esconder ou regular uma parte de um programa, mantendo o restante
do código alheio às questões internas que são resolvidas ou
implementadas dentro da subrotina.
10
Voltando ao exemplo
10 SUB:MOV R1, (R0)+
11
MOV R2, (R0)+
12
ADD R3, R1, R2
13
MOV (R0), R3
14
RTS
1 PRINC:MOV R0, #100
2
CALL SUB
3
MOV R0, #200
4
CALL SUB
5
MOV R0, #300
6
CALL SUB
7
MOV R0, #200
Vamos executá-lo!
CALL SUB
Desvio para Subrotina
• Guardar o endereço de
retorno
• Desviar a execução do
programa para a Subrotina
PC
12
13
10
12
11
14
End-R
3
RTS
Retorno para o programa
• Desviar a execução para o
endereço correto (End-R)
Como implementar as
instruções CALL e RTS?
11
Implementando uma subrotina
•
Vamos definir algumas estratégias para implementar subrotinas, determinando as
microoperações envolvidas nas instruções CALL e RTS.
•
Voltando para nosso programa inicial, mas agora simplificado:
PC
1 PRINC: MOV R0, #100
2
CALL SUB
3
MOV R0, #200
10 SUB:MOV R1, (R0)+
11
MOV R2, (R0)+
12
ADD R3, R1, R2
13
MOV (R0), R3
14
RTS
32
10
14
RL
3
ESTRATÉGIA 1: REGISTRADOR LIGANTE (RL)
O endereço de retorno é armazenado em um
registrador especial (RL)
CALL SUB
1. Armazena o endereço de retorno em RL:
RL ← (PC)
Endereço seguinte à
instrução CALL
2. Desvia a execução para a subrotina:
PC ← end-de-SUB
RTS
1. Desviar a execução do programa para
endereço contido em RL
PC ← (RL)
12
Implementando uma subrotina
1 PRINC: MOV R0, #100
2
CALL SUB
3
MOV R0, #200
10 SUB:MOV R1, (R0)+
11
MOV R2, (R0)+
12
ADD R3, R1, R2
13
MOV (R0), R3
14
RTS
ESTRATÉGIA 2: ENDEREÇO DE RETORNO JUNTO À SUBROTINA
O endereço de retorno é armazenado na primeira linha
da subrotina
Como?
Reservando a palavra de memória referente a primeira linha da
subrotina: pseudo-instrução DS
13
Implementando uma subrotina
1
2
3
PRINC: MOV R0, #100
CALL SUB
MOV R0, #200
10 SUB:DS 1
MOV R1, (R0)+
11
MOV R2, (R0)+
12
ADD R3, R1, R2
13
MOV (R0), R3
14
RTS
15
ESTRATÉGIA 2: ENDEREÇO DE RETORNO JUNTO À SUBROTINA
O endereço de retorno é armazenado na primeira linha
da subrotina
Como?
Reservando a palavra de memória referente a primeira linha da
subrotina: pseudo-instrução DS
CALL SUB
1. Endereço de retorno é armazenado no endereço SUB
Endereço seguinte à
instrução CALL
2. Desvia a execução para a subrotina:
SUB ← (PC)
PC ← end-de-SUB
RTS
1. Desviar a execução do programa para
endereço contido em SUB
PC ← (SUB)
14
Implementando uma subrotina
1
2
3
PRINC: MOV R0, #100
CALL SUB
MOV R0, #200
10 SUB:DS 1
MOV R1, (R0)+
11
MOV R2, (R0)+
12
ADD R3, R1, R2
13
MOV (R0), R3
14
RTS
15
ESTRATÉGIA 2: ENDEREÇO DE RETORNO JUNTO À SUBROTINA
Qual é a limitação destas duas
formas de implementação?
Para exemplificar, vamos
analisar um exemplo real com o
processador ARM...
15
Exemplo: ARM
SUBROTINA 1
PROG. PRINC
SUBROTINA 2
11
MOV R1,R2
20
SUB1: ...
40
SUB2: ...
12
BL SUB1
21
BL SUB2
41
...
22
...
42
BX LR
23
BX LR
43
13
...
14
NÃO é possível chamar uma subrotina
estando dentro de outra subrotina!
Como
solucionar?
R14(LR)
13
22
Uso da Pilha!
16
Implementando uma subrotina
1 PRINC: MOV R0, #100
2
CALL SUB
3
MOV R0, #200
10 SUB: MOV R1, (R0)+
CALL SUB2
11
RTS
12
14 SUB2:MOV R1, R3
RTS
15
ESTRATÉGIA 3: ENDEREÇO DE RETORNO ARMAZENADO NA PILHA
O endereço de retorno é armazenado na última posição
livre da pilha. Desta forma, pode-se chamar subrotinas
recursivamente
17
Implementando uma subrotina
1 PRINC: MOV R0, #100
2
CALL SUB
3
MOV R0, #200
10 SUB:MOV R1, (R0)+
CALL SUB2
11
RTS
12
14 SUB2:MOV R1, R3
RTS
15
12
3
PILHA
ESTRATÉGIA 3: ENDEREÇO DE RETORNO ARMAZENADO NA PILHA
O endereço de retorno é armazenado na última posição
livre da pilha. Desta forma, pode-se chamar subrotinas
recursivamente
CALL SUB
1. Endereço de retorno é armazenado na pilha
(SP) ← (PC)
SP ← (SP) + 1
RTS
1. Endereço de retorno é retirado da pilha e alocado em
PC
SP ← (SP) - 1
PC ← ((SP))
2. Desvia a execução para a subrotina:
PC ← end-de-SUB
18
Subrotinas
Agora que já sabemos estratégias de como implementar uma subrotina
usando as instruções CALL e RTS, precisamos abordar a questão de como
os dados são passados para a subrotina.
• Ao chamar uma subrotina através da instrução CALL, é necessário
informar onde estão os dados que ela irá manipular. Estes dados
formam os parâmetros reais.
• Ao declarar uma subrotina, deve-se indicar quais variáveis ela irá
manipular. Estas variáveis são conhecidas como parâmetros
formais. Toda vez que a subrotina é chamada, estes parâmetros são
substituídos pelos reais, enviados para a subrotina.
MOV R0, #100
CALL SUB (A,B)
MOV R0, #200
SUBROTINA SUB (X,Y)
X = Y*3
Y=3+X
Finalmente, como os dados são passados
para a subrotina?
19
Passagem de parâmetros
• Considere que os dados que a subrotina irá manipular estejam na memória.
• Existem duas formas de informá-los à subrotina:
Por Valor
Por Referência
Passo para a subrotina
uma cópia do dado
Passo para a subrotina
o endereço do dado
Como?
Passando o conteúdo do endereço
Como?
Informando o endereço #label
Implicações
Toda vez que a subrotina manipula um
dado, ela está alterando uma cópia dele,
mantendo inalterado o dado original.
Implicações
Desta forma, toda vez que a subrotina
manipula um dado, ela está
alterando-o permanentemente.
Mas como os dados são alocados na memória?
20
Passagem
desãoparâmetros
Como os dados
alocados na memória?
Basicamente há duas formas de alocar dados na
memória:
1. Através de periféricos:
Mouse, teclado, tela touchscreen, HD, enviam
dados para os processadores. Estes dados são
alocados, primeiramente, na memória e ficam
disponíveis para serem acessados pelos
programas.
2. Através de pseudo-instruções:
É um tipo especial de instrução (veremos mais
adiante), não executável, que insere valores em
posições de memória ou reserva espaço para
receber valores:
Reserva X palavras da memória a
partir da posição da pseudoinstrução.
DW X Posição de memória desta pseudoinstrução recebe o valor X.
DS X
21
Passagem de parâmetros
• Vamos analisar mais detalhadamente como se procede a passagem
de parâmetros por valor e por referência:
SUB: ...
DADO: DW 200
RESULT: DS 1
MOV R1 , (R3)
MOV DADO , R1 valor
...
MOV #RESULT , R3 referência
RTS
CALL SUB
DADO: DW 200
RESULT: DS 1
MOV #DADO , R1 referência
CALL SUB
MOV R2, RESULT
SUB: ...
MOV (R1),R2
...
ADD #10, R2
RTS
22
Passagem de parâmetros
• Vamos identificar a passagem de parâmetros no programa abaixo e
verificar, passo a passo, as posições de memória dos dados de entrada
e saída:
PROGRAMA
SUBROTINA
PASSAGEM DE PARÂMETROS
MOVE DAD1, DIN1 valor
MOVE DAD2, DIN2
CALL SUB
valor
MOVE RES, RESU
STOP
DAD1: DW 5
DAD2: DW 18
RESU: DS 1
DIN1: DS 1
DIN2: DS 1
RES: DS 1
SUB: ADD DIN1, DIN2
MOVE DIN2, RES
RTS
INICIALIZAÇÃO
DOS DADOS
23
Passagem de parâmetros
•
(1)
(2)
(3)
(4)
(5)
(6)
Considere que a chamada da subrotina foi implementada com pilha, e que DADO está
na posição 20 de memória. Cada instrução ocupa uma palavra.
MOV #0,SP
MOV #DADO,R1
PUSH R1
CALL SUB
POP R1
MOV R1 , RES
STOP
DADO: DW 50
RES: DS 1
...
(100) SUB: POP R3
POP R2
(101)
MOV (R2),R5
(102)
SUB #3 , R5
(103)
PUSH R5
(104)
PUSH R3
(105)
RTS
(106)
PC ← 5
Inic.
(1)
(2)
(3)
(4)
(100)
(101)
(102)
(103)
(104)
(105)
(106)
(5)
(6)
DADO
RES
R1
R2
R3
R5
SP
50
50
50
X
X
X
X
X
20
X
X
X
X
X
X
X
X
X
X
0
50
50
X
X
20
X
X
X
X
X
50
50
50
50
50
X
20
20
20
20
20
X
20
20
20
20
5
5
5
5
5
20
20
47
47
20
20
20
20
5
5
5
5
50
50
50
50
X
X
X
X
X
X
X
47
20
0
1
X
X
X
X
X
X
20
X
1
2
X
5
X
1
X
50
47
47
0
0
0
1
20 5
20 5
20 5
20 5
47 5
47
47
47
47
2
1
0
0
0
20
47 5
47 X
47 X
47 X
24
Conclusão
 Uma forma eficiente de escrever um programa é através da
modularização de partes repetidas do código.
 Estes módulos podem ser acessados pelo programa em diferentes
momentos e com diferentes dados de entrada – são conhecidos como
subrotinas.
 A subrotina é chamada por uma instrução especial (CALL) e sua
execução termina com a instrução RTS.
 As instruções CALL e RTS podem ser implementadas através de 3
estratégias: via registrador RL, via endereço de retorno na primeira
linha da subrotina e via pilha.
 Os dados podem ser passados para a subrotina de duas formas
(passagem de parâmetros): por valor, onde passo uma cópia do
dado e por referência, onde passo o endereço do dado.
 O uso da pilha é de extrema importância nas chamadas de
subrotina, já que permite que elas chamem outras subrotinas (ou elas
próprias, num esquema recursivo). Tal fato faz seu uso ser bastante
comum nos processadores.
25
Créditos
 Este material está baseado nas notas de aula elaboradas pelo
Prof. Léo Pini e pelo aluno de doutorado Tiago Novaes.
26
Download