CALL SUB - CEB/Unicamp

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
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?
3
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
4
Exemplo
 Observe que parte do código se repete ao longo do
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 essa
redundância?
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.
5
Exemplo
 Observe que parte do código se repete ao longo do
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
Instrução que
chama a subrotina
O que poderíamos
fazer para resolver essa
redundância?
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.
MOV R0, #300
6
Exemplo
 Observe que parte do código se repete ao longo do
Criar um subprograma ou uma subrotina!
PRINC: MOV R0, #100
CALL SUB
MOV R0, #200
CALL SUB
MOV R0, #300
CALL SUB
Instrução que
chama a subrotina
O que poderíamos
fazer para resolver essa
redundância?
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.
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
7
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 sua execução, o
controle deverá ser retornado ao ponto imediatamente posterior ao da
ocorrência do desvio.
8
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.
9
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
14
12
11
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?
10
Implementando uma subrotina
•
Vamos definir algumas estratégias para implementar
microoperações envolvidas nas instruções CALL e RTS.
•
Voltando para nosso programa inicial, mas agora simplificado:
subrotinas,
determinando
as
PC
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
32
10
14
RL
3
ESTRATÉGIA 1: REGISTRADOR LIGANTE (RL)
O endereço de retorno é armazenado em um registrador
especial (RL)
CALL SUB
RTS
1. Armazena o endereço de retorno em RL:
RL ← (PC)
2. Desvia a execução para a subrotina:
PC ← mem SUB
Endereço seguinte à
instrução CALL
1. Desviar a execução do programa para
endereço contido em RL
PC ← (RL)
11
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
12
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
Reservando a palavra de memória referente a primeira linha da subrotina:
pseudo-instrução DS
Como?
CALL SUB
RTS
1. Endereço de retorno é armazenado no endereço SUB
SUB ← (PC)
2. Desvia a execução para a subrotina:
PC ← end-de-SUB
Endereço seguinte à
instrução CALL
1. Desviar a execução do programa para
endereço contido em SUB
PC ← (SUB)
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
Qual é a limitação destas duas
formas de implementação?
Para exemplificar, vamos analisar
um exemplo real com o processador
ARM...
14
Exemplo: ARM
SUBROTINA 1
PROG. PRINC
SUBROTINA 2
11
MOV R1,R2
20
SUB1: ...
40
SUB2: ...
12
BL SUB1
21
BL SUB2
41
...
13
...
22
...
42
BX LR
23
BX LR
43
14
NÃO é possível chamar uma subrotina estando
dentro de outra subrotina!
R14(LR)
Como solucionar?
13
22
Uso da Pilha!
15
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
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
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
17
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?
18
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
Implicações
Toda vez que a subrotina manipula um
dado, ela está alterando uma cópia dele,
mantendo inalterado o dado original.
Como?
Informando o endereço #label
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?
19
Passagem
de parâmetros
Como os dados
são 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:
DS X
Reserva X palavras da memória a partir
da posição da pseudo-instrução.
DW X
Posição de memória desta pseudoinstrução recebe o valor X.
20
Passagem de parâmetros
• Vamos analisar mais detalhadamente como se procede a passagem de
parâmetros por valor e por referência:
DADO: DW 200
RESULT: DS 1
MOV DADO , R1
MOV #RESULT , R3
CALL SUB
DADO: DW 200
RESULT: DS 1
MOV #DADO , R1
CALL SUB
MOV R2, RESULT
valor
referência
referência
SUB: ...
MOV R1 , (R3)
...
RTS
SUB: ...
MOV (R1),R2
...
ADD #10, R2
RTS
21
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
MOVE DAD2, DIN2
CALL SUB
MOVE RES, RESU
STOP
DAD1: DW 5
DAD2: DW 18
RESU: DS 1
valor
valor
DIN1: DS 1
DIN2: DS 1
RES: DS 1
SUB: ADD DIN1, DIN2
MOVE DIN2, RES
RTS
INICIALIZAÇÃO DOS
DADOS
22
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
0
1
50
50
50
X
X
X
X
X
20
X
X
X
X
X
X
X
X
X
X
0
X
X
X
X
X
X
50
50
X
X
20
X
X
X
X
X
20
X
1
2
20
X
5
50
50
50
50
50
X
20
20
20
20
20
X
X
1
20
20
20
20
5
5
5
5
5
X
50
47
47
0
0
0
1
20
20
20
20
47
5
5
5
5
5
20
20
47
47
20
20
20
20
5
5
5
5
47
47
47
47
2
1
0
47
47
47
0
47
5
X
X
X
50
50
50
50
X
X
X
X
X
X
X
47
20
0
23
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.
24
Créditos
 Este material está baseado nas notas de aula elaboradas pelo Prof. Léo
Pini e pelo aluno de doutorado Tiago Novaes.
25
Download