MIPS Arquitectura de Computadores Serviços de Sistema

Propaganda
Arquitectura de Computadores
ARQC
MIPS
Serviços de Sistemas
Exemplos
Serviços de Sistema
Exemplo 1
Fonte: http://usuarios.upf.br/~brusso/arq2/spim.html
Somar duas variáveis em um registrador
Código em C
register int a=1, b=3, c;
c = a + b;
Código em linguagem de montagem MIPS (usar os có
códigos de serviç
serviço)
# exe1.s - Soma duas variáveis em um registrador
.text
.globl __start
__start:
li $t0, 1
# $t0 = 1
li $t1, 3
# $t1 = 3
add $t2, $t1, $t0
# $t2 = $t1 + $t0
li $v0, 10
# Serviço 10 : Exit
syscall
Exemplo 2
Fonte: http://usuarios.upf.br/~brusso/arq2/spim.html
Somar duas variáveis na memória
Código em C
Código em linguagem de montagem MIPS
static int va=0, vb=5, vc=10;
a = b + c;
# exe2.s soma duas variaveis na memoria
# segmento de dados
.data
va: .word
0
vb: .word
5
vc: .word
10
# segmento de texto
.text
.globl __start
__start:
lw $t0, vb
# Carrega vb em $t0
lw $t1, vc
# Carrega vc em $t1
add $t2, $t1, $t0
# $t2 = $t1 + $t0
sw $t2, va
# Armazena $t2 em va
li $v0, 10
# Serviço 10 : exit
syscall
Exemplo 3
Fonte: http://usuarios.upf.br/~brusso/arq2/spim.html
Ler um número inteiro
Código em C
printf("Digite um numero:");
var = read_int();
Código em linguagem
de montagem MIPS
# ex3.s - Ler um número inteiro
.data
aviso: .asciiz "Digite um numero:"
.text
.globl __start
__start:
la $a0, aviso # Carrega endereco da string em $a0
li $v0, 4
# Serviço 4 : imprime string
syscall
li $v0, 5
# Serviço 5 : lê inteiro
syscall
add $t1, $t1, $v0 # $t1 = $v0
li $v0, 10
# Serviço 10 : exit
syscall
Exemplo 4
Execução condicional
Código em C
if(var1<5){
var2 = var2 + var1;
var1 = 0;
}
else
var2 = var2 + 1;
Código em linguagem
de montagem MIPS
Fonte: http://usuarios.upf.br/~brusso/arq2/spim.html
# ex4.s – Execução condicional
.data
var1: .word 1
var2: .word 5
.text
.globl __start
__start:
lw $s0, var1
# carrega var1
lw $s1, var2
# carrega var2
slti $t0, $s0, 5
# testa se var1 < 5
beq $t0, $zero, senao # se falso, pula p/ senao
add $s1, $s1, $s0
# var2 = var2 + var1
li $s0, 0
# var1 = 0
sw $s0, var1
# armazena var1
sw $s1, var2
# armazena var2
j fim_se
# pula p/ fim
senao:
addi $s1, $s1, 1 # var2 = var2 + 1
sw $s1, var2
# armazena var2
fim_se:
li $v0, 10
# exit
syscall
Exemplo 5
Manipulação de Vetores
Código em C
int vetor[] = {10, 5, 8, 20, 43};
int i=0;
do{
printf("%d\n", vetor[i]);
i++;
} while(i<5);
Código em linguagem
de montagem MIPS
Fonte: http://usuarios.upf.br/~brusso/arq2/spim.html
# ex5.s – Manipulação de Vetores
.data
vetor: .word 10, 5, 8, 20, 43
linha: .asciiz "\n"
.text
.globl __start
__start:
la $t0, vetor
# endereco do vetor
li $t1, 0
#i
laco: li $v0, 1
# imprime inteiro
lw $a0, 0($t0)
# valor a imprimir
syscall
li $v0, 4
# imprime string
la $a0, linha
# nova linha
syscall
addi $t0, $t0, 4
# proximo endereco
addi $t1, $t1, 1
# proximo i
blt $t1, $t2, laco
# ir p/ laco se $t1<$t2
li $v0, 10
# termina
syscall
Chamada de Procedimentos
• Quando uma função deve ser chamada, deve-se salvar os parâmetros a
serem passados a funções nos registradores $a0-$a3 e chamar a função
usando a instrução jal (jump-and-link) – O conteúdo de PC + 4 será salvo no
registrador $ra de tal modo que ao final da função uma chamada jr $ra fará
com que o programa execute a instrução posterior àquela que chamou a
função.
• Mais de quatro parâmetros podem ser passados usando uma pilha LIFO (Last
In Fisrt Out) – MIPS mantém um registrador, o $sp (Stack Pointer) para
manter o endereço do topo da pilha
• Convenção para a pilha (motivos históricos):
• Operação Push (inserir dados na pilha): endereço da pilha diminui ($sp-x)
• Operação Pop (retirar dados da pilha): endereço da pilha aumenta ($sp+x)
• Para o retorno do cálculo realizado no função, os registradores $v0-$v1
devem ser utilizados
Exemplo 6
Fonte: http://usuarios.upf.br/~brusso/arq2/spim.html
Chamada de procedimento 1
Código em C
Código em linguagem
de montagem MIPS
void main(void)
{
int va, vb;
va = cubo(2);
vb = cubo(va);
}
int cubo(int num)
{
int temp;
temp = num*num*num;
return(temp);
}
• $a0-$a3 = registradores de
argumentos para passagem de
parâmetros
• $v0-$v1 = registradores de valor
para valores de retorno
• $ra = registrador de endereço de
retorno (partida + 1 => PC + 4)
# ex6.s – Chamada de procedimento
.text
.globl __start
# Função main()
__start:
li $a0, 2
# Passa valor 2 como parâmetro
jal cubo
# Chama procedimento cubo
move $s0, $v0
# Atribui valor de retorno p/ va
move $a0, $s0
# Passa va como parâmetro
jal cubo
# Chama procedimento cubo
move $s1, $v0
# Atribui valor de retorno p/ vb
li $v0, 10
# Servico 10: exit
syscall
# Função cubo()
cubo: mul $t0, $a0, $a0
mul $t0, $t0, $a0
move $v0, $t0
jr $ra
#
#
#
#
temp = num * num
temp = temp * num
Define valor de retorno
Retorna do procedimento
Exercício 7
Chamada de procedimento 2: comente o código apresentado.
Código em C
main() {
x = soma3(a, b, c)
}
soma3(x, y, z) {
return( soma( x, soma(y, z)));
}
soma(x1, x2) {
return( x1+x2 );
}
# ex7.s: Subrotinas aninhadas
# Author: Fernando Gehm Moraes
.text
.globl __start
Código em linguagem
__start:
la
$s1, var_a
de montagem MIPS
lw
$s1, 0($s1)
la
$s2, var_b
lw
$s2, 0($s2)
la
$s3, var_c
lw
$s3, 0($s3)
addiu $sp,$sp,-16
sw
$ra, 0($sp)
sw
$s1, 4($sp)
sw
$s2, 8($sp)
sw
$s3,12($sp)
jal
soma3
lw
$ra,0($sp)
lw
$s4,4($sp)
addiu $sp,$sp,16
end:
j
$ra
Exercício 7
Fonte: http://usuarios.upf.br/~brusso/arq2/spim.html
Chamada de procedimento: comente o código apresentado
M
soma3: lw
$t0, 4($sp)
lw
$t1, 8($sp)
M
sw
addiu $sp,$sp,-12
sw
$ra, 0($sp)
sw
$t0, 4($sp)
sw
$t1, 8($sp)
jal
soma
lw
$ra,0($sp)
lw
$t0,4($sp)
addiu $sp,$sp,12
lw
$t1, 12($sp)
addiu $sp,$sp,-12
sw
$ra,0($sp)
sw
$t0,4($sp)
sw
$t1,8($sp)
jal
soma
lw
$ra,0($sp)
lw
$t0,4($sp)
addiu $sp,$sp,12
j
$t0,4($sp)
$ra
soma:
lw
$t7,4($sp)
lw
$t8,8($sp)
addu $t7,$t7,$t8
sw
$t7,4($sp)
jr
$ra
.data
var_a: .word 0x00AA0000
var_b: .word 0x0000BB00
var_c: .word 0x000000CC
# Final do arquivo
Exercícios
1. Multiplicar dois números usando o seguinte procedimento:
1.
2.
3.
4.
5.
Carrega o valor de A em $s0 (0x01234ABC )
Carrega o valor de B em $s1 (0x004A5F32 )
Zerar o registrador $s2 que conterá o resultado (dica: usar xor)
Carrega o registrador $t0 com 1, para servir como máscara para comparação
Verifica se B ($s1) for zero.
1. Se afirmativo terminou a multiplicação, salta para passo 10
6. verifica se o bit menos significativo de B ($s1) e' igual a '1' ($t0)
1. Se afirmativo acumula o resultado ($s2) com A ($s0)
7. Desloca B ($s1) um bit para a direita
8. Desloca A ($s0) um bit para a esquerda
9. Volta para o passo 5
10. Grava o conteúdo de $s2 no endereço res
2. Melhorar o programa anterior permitindo que o usuário forneça o valor de
cada operando. Garantir que após o cálculo, os dados sejam apresentados
ao usuário.
3. Escreva uma função que calcule o fatorial de um número. Escreva então
um programa que solicite que o usuário introduza um valor e que na
seqüência chame a função fatorial, calcule o fatorial do número e o
apresente ao usuário.
Download