Apresentação do PowerPoint

Propaganda
ORGANIZAÇÃO E ARQUITETURA DE
COMPUTADORES I
AULA 05: LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Prof. Max Santana Rolemberg Farias
[email protected]
Colegiado de Engenharia de Computação
O QUE SÃO PROCEDIMENTOS?
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
• Procedimentos são um conjunto de instruções com
função definida.
– Realizam uma série de operações com base em valores passados
por parâmetros.
– Podem retornar valores (função).
• A chamada de um procedimento, faz com que o programa
execute as instruções contidas no procedimento.
– Ao término da execução de um procedimento, o programa deve
executar a instrução seguinte à chamada do procedimento.
PARA QUE UTILIZAMOS PROCEDIMENTOS E
FUNÇÕES?
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
• São utilizados para estruturar um programa.
– Facilita entendimento
– Aumenta reuso de código (reutilização do código)
COMO UM PROCEDIMENTO É EXECUTADO?
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Existem 6 passos para a execução de um procedimento:
1. O programa coloca os parâmetros em um lugar onde o procedimento
chamado possa acessá-los.
2. O programa transfere o controle para o procedimento.
3. O procedimento acessa os valores necessários para executar a sua
tarefa.
4. O procedimento executa sua tarefa, gerando valores.
5. O procedimento (chamado) coloca os valores gerados em um local onde
o programa (chamador) possa acessá-lo.
6. O procedimento transfere o controle de volta para o ponto do programa
que o chamou.
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
• Uma CPU simples oferecem alguns registradores
específicos para dá suporte a procedimentos.
– Registradores para argumentos ($a0 - $a3): Quatro
registradores usados como argumentos para passagem de
parâmetros.
– Registradores de retorno ($v0 - $v1): Dois registradores usados
para retornar valores.
– Registradores de endereço de retorno ($ra): Registrador que
guarda o endereço de retorno (return address) para o ponto do
programa que chamou o procedimento.
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
• Uma CPU simple oferecem duas instruções para dá
suporte a procedimentos.
– Instrução Jump And Link (jal): Pula para o endereço inicial do
procedimento e salva o endereço de retorno (endereço da
próxima instrução após chamada).
$ra <- PC + 4
– Instrução Jump Refister (jr): Pula para o endereço armazenado
no registrador. No caso de retorno de procedimentos, o
registrador deve ser o $ra.
jr $ra
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Formato das Instruções jal
• Salta para o endereço especificado, salvando o endereço
da próxima instrução em $ra.
jal addr
$ra <- PC + 4
Assembly
jal 0x200C
Opcode
IMM
0x2
0x200C
Linguagem de Máquina
0000 1000 0000 0000 0010 0000 0000 1100
(0x0800200C)
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Formato das Instruções jr
• Desvio incondicional para endereço guardado em
registradores. Para suporte a procedimento o registrador
é o $ra.
jr $ra
Assembly
Jr $ra
Opcode
RS
RT
RD
Shamt
Funct
0x0
31
0
0
0x0
0x8
Linguagem de Máquina
0000 0011 1110 0000 0000 0000 0000 1000
(0x03E00008)
COMO PRESERVAR O CONTEXTO DO
PROGRAMA?
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
• Restaurar os valores dos registradores usados pelo
procedimento para o valor que tinha antes da chamada.
– Para isso o conteúdo dos registradores deve ser salvo na
memória. E depois da execução do procedimento, estes
registradores devem ter seus valores restaurados.
• Se as chamadas forem recursivas, é conveniente o uso de
uma pilha.
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Implementação com Pilha
• A implementação com pilha é uma solução comum, visto
que muitos procedimentos precisam de mais
registradores que os especificados para o procedimento.
– Pode se utilizar parte da memória como pilha.
• Utilizando o apontador de pilha (Stack Pointer), que é um registrador
especifico ($sp) usado para guardar o endereço do topo da pilha da
chamada de procedimentos (o registrador guarda o endereço do topo).
• A pilha cresce do endereço mais alto para o mais baixo.
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Organização da memória
•
Segmento de texto (text)
– Código.
•
Dados estáticos (static data)
– Variáveis globais.
– Variáveis estáticas.
– Em uma CPU simples o registrador $gp guarda o
início do segmento.
•
Dados dinâmicos (heap)
– O malloc da linguagem C
•
Pilha (stack)
– Variáveis locais
– Registradores
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Implementação com Pilha
• Inserir dado na pilha (Push)
$sp <- $sp – 4
• remover dado na pilha (Pop)
$sp <- $sp + 4
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Procedimento simples
Linguagem de Alto Nível
int main(){
simples();
...
}
void simples(){
return;
}
Linguagem de Montagem
0x00400200 jal 0x00401020 #simples()
0x00400204 ...
0x00401020 jr $ra #return
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Procedimento com argumentos
Linguagem de Alto Nível
int main(){
int y;
...
y = diff_sums(2,3,4,5);
...
}
int diff_sums(int f, int g, int h, int i){
int result;
result = (f + g) – (h + i);
return result;
}
A variável y é armazenada nos registrador $s0
Linguagem de Montagem
0x00400200
0x00401020
0x00401024
0x00401028
0x0040102C
0x00401030
0x00401034
0x00401038
0x00401048
0x0040104C
0x00401050
0x00401054
0x00401058
...
addi $a0 $zero 2 #arg0=2
addi $a1 $zero 3 #arg1=3
addi $a2 $zero 4 #arg2=4
addi $a3 $zero 5 #arg3=5
jal 0x00401048 #diff_sums
add $s0 $v0 $zero #return
...
add $t0 $a0 $a1 #t0=f+g
add $t1 $a2 $a3 #t1=h+i
sub $s0 $t0 $t1 #s0=t0-t1
add $v0 $s0 $zero #return
jr $ra
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Procedimento usando a pilha
Linguagem de Alto Nível
int main(){
int y;
...
y = media(2,3,5,6);
...
}
int media(int x, int y, int z, int
w){
int result;
result = (x + y + z + w)/4;
return result;
}
Linguagem de Montagem
0x00400200
0x00401020
0x00401024
0x00401028
0x0040102C
0x00401030
0x00401034
0x00401038
...
addi $a0 $zero 2 #arg0=2
addi $a1 $zero 3 #arg1=3
addi $a2 $zero 5 #arg2=5
addi $a3 $zero 6 #arg3=6
jal 0x00401048 #media
add $s0 $v0 $zero #return
...
0x00401048
0x0040104C
0x00401050
0x00401054
addi $sp $sp -12 #reservando
sw $t1, 8($sp) #salva $t1
sw $t0, 4($sp) #salva $t0
sw $s0, 0($sp) #salva $s0
$t1 (0x5)
$t0 (0x4)
$s0 (0x3)
A variável y é armazenada no registrador $s0. Os valores de $s0, $t0, $t1 são: 0x3, 0x4 e 0x5.
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Procedimento usando a pilha (Continuação)
Linguagem de Alto Nível
int main(){
int y;
...
y = media(2,3,5,6);
...
}
int media(int x, int y, int z, int w){
int result;
result = (x + y + z + w)/4;
return result;
}
Linguagem de Montagem
0x00401038 ...
0x00401048
0x0040104C
0x00401050
0x00401054
0x00401058
0x0040105C
0x00401060
0x00401064
0x00401068
addi $sp $sp -12 #reservando
sw $t1, 8($sp) #salva $t1
sw $t0, 4($sp) #salva $t0
sw $s0, 0($sp) #salva $s0
add $t0 $a0 $a1 #t0=x+y
add $t1 $a2 $a3 #t1=z+w
add $s0 $t0 $t1 #s0=x+y+z+w
srl $s0 $s0 2 #(x+y+z+w)/4
add $v0 $s0 $zero #return
$t1 (0x5)
$t0 (0x4)
$s0 (0x3)
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Procedimento usando a pilha (Continuação)
Linguagem de Alto Nível
int main(){
int y;
...
y = media(2,3,5,6);
...
}
int media(int x, int y, int z, int w){
int result;
result = (x + y + z + w)/4;
return result;
}
Linguagem de Montagem
0x00401038 ...
0x00401058
0x0040105C
0x00401060
0x00401064
0x00401068
0x0040106C
0x00401070
0x00401074
0x00401078
0x0040107C
add $t0 $a0 $a1 #t0=x+y
add $t1 $a2 $a3 #t1=z+w
add $s0 $t0 $t1 #s0=x+y+z+w
srl $s0 $s0 2 #(x+y+z+w)/4
add $v0 $s0 $zero #return
lw $s0 0($sp) #recupera $s0
lw $t0 4($sp) #recupera $t0
lw $t1 8($sp) #recupera $t1
addi $sp $sp, 12 #ajusta top
jr $ra #retorna para main
$t1 (0x5)
$t0 (0x4)
$s0 (0x3)
É POSSÍVEL PROCEDIMENTOS RECURSIVOS?
LINGUAGEM DE MONTAGEM:
SUPORTE A PROCEDIMENTOS
Linguagem de Alto Nível
Linguagem de Montagem
Procedimento recursivo
int main(){
y = fatorial(3);
...
}
int fatorial(int n){
if (n <= 1)
return 1;
else
return (n * fatorial(n – 1);
}
0x00400200 jal 0x00401020 #fatorial(3)
0x00400204 add $s0 $v0 $zero #y=return
0x0040101C
0x00401020
0x00401024
0x00401028
0x0040102C
0x00401030
0x00401034
0x00401038
0x0040103C
0x00401040
0x00401044
0x00401048
0x0040104C
0x00401050
0x00401054
0x00401058
0x0040105C
addi $a0 $zero 3 #arg0=3
addi $sp $sp -8 #ajusta a pilha
sw $a0 4($sp) #salva $a0
sw $ra 0($sp) #salva $ra
addi $t0 $zero 2 #t0=2
slt $t0 $a0 $t0 #a0<t0?1:0
beq $t0 $zero 0x00401048
addi $v0 $zero 1 #return 1
addi $sp $sp 8 #restaura pilha
jr $ra #return
addi $a0 $ao -1 #n=n-1
jal 0x00401020 #chamada recursiva
lw $ra 0($sp) #recupera $ra
lw $a0 4($sp) #recupera $a0
addi $sp $sp 8 restaura $sp
mul $v0 $a0 $v0 #n*fatorial(n-1)
jr $ra
Download