i = i + j

Propaganda
Anotações da 2a Edição
OBS: Essas anotações são adaptações do material
suplementar (apresentações PPT) ao Livro do
Hennessy e Patterson. Supõe-se que os estudantes
tenham noções de lógica digital e linguagem
assembly para o entendimento das aulas.
1
Compilando códigos para MIPS
2
Código C → Código MIPS
•
•
•
Compilador faz a conversão:
C code:
A = B + C;
E = F - A;
MIPS code:
add $s0, $s1, $s2
sub $s4, $s5, $s0
Operandos só em registradores: load/store para trabalhar com
variáveis do programa.
Instruções R, I, J (aulas anteriores...)
3
Compilando indexação de vetores
•
Seja A um vetor de inteiros (4 bytes) e que o compilador tenha
associado as variáveis g, h e i com os registradores $s1, $s2 e $s4.
Considere que o endereço inicial (ou de base) do vetor está em $s3.
•
O código a seguir é uma possível compilação do trecho de código em
C para instruções assembly MIPS:
g = h + A[i];
1) Converter indexação de word para bytes:
add $t1,$s4,$s4
# Temp reg $t1 = 2 * i
add $t1,$t1,$t1
# Temp reg $t1 = 4 * i
2) Para pegar o endereço de A[i], deve-se adicionar $t1 à base de A em $s3:
add $t1,$t1,$s3
# $t1 = endereço de A[i] (4 * i + $s3)
3) Usar o endereço calculado para carregar A[i] num reg temporário:
lw $t0,0($t1)
# Temp reg $t0 recebe A[i]
4) Finalmente, adicionar A[i] a h e colocar a soma em g:
add $s1,$s2,$t0
# g = h + A[i]
4
Compilando if-then-else
•
Assumindo que as 5 variáveis f, g, h, i e j correspondem aos 5
registradores de $s0 a $s4, o código compilado MIPS será o
mostrado abaixo para a construção if em C:
if (i==j) f = g + h; else f = g - h;
bne $s3,$s4,Else
# go to Else if i != j
add $s0,$s1,$s2
# f = g + h (desvia se i != j)
j Exit
Else: sub $s0,$s1,$s2 # f = g - h (desvia de i == j)
Exit:
5
Compilando if-then-else (Versão 2)
•
Assumindo que as 5 variáveis f, g, h, i e j correspondem aos 5
registradores de $s0 a $s4, o código compilado MIPS será o
mostrado abaixo para a construção if em C:
if (i==j) f = g + h; else f = g - h;
beq $s3,$s4,Else
# go to Else if i ! j
sub $s0,$s1,$s2
# f = g - h (desvia de i == j)
j Exit
Else: add $s0,$s1,$s2 # f = g + h (desvia se i != j)
Exit:
6
Compilando um loop while
•
Assumindo que as 3 variáveis i, j, k correspondem aos 3
registradores de $s3 a $s5, e que a base do vetor V está em $s6. O
código compilado MIPS para a construção em C será:
while (V[i] == k) i = i + j;
1) Carregar V[i] num registrador temporário:
Loop: add $t1,$s3,$s3
add $t1,$t1,$t1
add $t1,$t1,$s6
lw $t0,0($t1)
# reg temporário $t1 = 2 * i
# reg temporário $t1 = 4 * i
# $t1 = endereço de V[i]
# reg temporário $t0 = V[i]
2) A próxima instrução realiza o teste do loop, saindo se V[i] != k :
bne $t0,$s5,Exit
# go to Exit se V[i] != k
3) A próxima instrução é somar j e i:
add $s3,$s3,$s4
4) Finalmente, chega-se ao fim do loop:
j Loop
Exit:
#i=i+j
# go to Loop no início do código
7
Compilando um switch a partir de uma Tabela de
Endereços de Desvio
•
O trecho em C seleciona 1 entre 4 alternativas dependendo do valor
assumido pela variável k, cujo domínio é 0, 1, 2 e 3.
switch (k) {
case 0: f = i + j; break;
case 1: f = g + h; break;
case 2: f = g - h; break;
case 3: f = i - j;
}
•
Suponha que as variáveis de f a k correspondem as 6 variáveis de $s0 a
$s5, e que o registrador $t2 contenha o valor inteiro 4 e o registrador $t4
o valor inicial da sequência de labels L0, L1, L2 e L3 armazenados na
memória.
Qual o código correspondente em assembly MIPS?
•
8
Código do switch em MIPS
slt $t3, $s5, $zero
bne $t3, $zero, Exit
slt $t3, $s5, $t2
beq $t3, $zero, Exit
add $t1, $s5, $s5
add $t1, $t1, $t1
add $t1, $t1, $t4
lw $t0, 0 ($t1)
jr $t0
L0:
add $s0, $s3,
j Exit
L1:
add $s0, $s1,
j Exit
L2:
sub $s0, $s1,
j Exit
L3:
sub $s0, $s3,
Exit:
Testa se 0 <= k < 4
$s5 armazena k
Salva em $t0 o endereço de Li
Li depende de $s5
$s4
$s2
$s2
$s4
9
Código MIPS compilado
O que tem
aqui dentro?
10
Código compilado MIPS
•
O que faz o código abaixo?
.text
.globl main
main:
li $t0,4
li $t1,6
beq $t0,$t1,sai
subu $t1,$t1,1
j fim
sai:
addu $t0,$t0,2
fim:
j $ra
#
#
#
#
#
#
#
Inicia uma área de código
Label como visibilidade global
Declaração do label main
i=4;
j=6;
if(i==j)
j=j-1; Subtrai sem considerar overflow
# i=i+2; (Soma sem considerar overflow)
# Retorna para o programa que chamou
11
Exemplo 1
.text
.globl main
main:
li $t0,4
li $t1,6
beq $t0,$t1,salto
subu $t1,$t1,1
j fim
salto:
addu $t0,$t0,2
fim:
j $ra
#
#
#
#
#
#
#
Inicia uma área de código
Label como visibilidade global
Declaração do label main
i=4;
j=6;
if(i==j)
j=j-1; (Subtrai sem considerar overflow)
# i=i+2; (Soma sem considerar overflow)
# Retorna para o programa que chamou
12
Exemplo 2
.text
.globl main
main:
move $t0, $zero
# i=0;
move $t1, $zero
# int sum = 0;
loop:
mul
$t2, $t0, $t0
# i * i
addu $t1, $t1, $t2
# sum = sum + i * i;
addu $t0, $t0, 1
# i=i+1
ble
$t0, 100, loop
# desvia para loop se i<=100
################ printf("\nThe sum from 0 .. 100 is %d", sum); ###############
la
$a0, str
# Atribui o endereço de str para o registrador $a0
li
$v0, 4
# $v0=4 imprime a string endereçada por $a0 no syscall
syscall
# Chamada ao SO
move $a0, $t1
# Atribui o valor de $t1 (inteiro) para o registrador $a0
li
$v0, 1
# $v0=1 imprime o valor armazenado em $a0 no syscall
syscall
# Chamada ao SO
j
$ra
.rdata
# Inicia uma área de dados
str:
.asciiz "\nThe sum from 0 .. 100 is " # Declaração de caracteres ASCII (string)
13
Chamadas de SO - syscall
•
•
•
Alguns serviços do sistema, principalmente para entrada e saída, podem ser
utilizados em programas em assembly MIPS.
Os conteúdos dos registradores MIPS não são afetados pela chamada de
sistema (system call), exceto para registradores de resultados.
Como usar serviços do sistema com SYSCALL?
1. Carregar o número do serviço no registrador $v0.
2. Carregar os valores dos argumentos, se houver, em $a0, $a1, $a2, ou $f12
especificados.
3. Lançar a instrução SYSCALL.
4. Recuperar os valores de retorno, se houver, a partir dos registradores de
resultado especificados.
•
Ex: Mostrar o valor armazenado em $t0 no console (saída padrão)
li $v0, 1
# serviço
add $a0, $t0, $zero # carrega
argumento
syscall
# Chamada
1: print um integer
o valor desejado no registrador de
argumento $a0, using pseudo-op
de sistema
Ver: http://courses.missouristate.edu/kenvollmar/mars/help/syscallhelp.html
14
Exemplo de I/O em arquivo
# Sample MIPS program that writes to a new file.
#
by Kenneth Vollmar and Pete Sanderson
.data
fout:
.asciiz "testout.txt"
# filename for output
buffer: .asciiz "The quick brown fox jumps over the lazy dog."
.text
###############################################################
# Open (for writing) a file that does not exist
li
$v0, 13
# system call for open file
la
$a0, fout
# output file name
li
$a1, 1
# Open for writing (flags are 0: read, 1: write)
li
$a2, 0
# mode is ignored
syscall
# open a file (file descriptor returned in $v0)
move $s6, $v0
# save the file descriptor
###############################################################
# Write to file just opened
li
$v0, 15
# system call for write to file
move $a0, $s6
# file descriptor
la
$a1, buffer
# address of buffer from which to write
li
$a2, 44
# hardcoded buffer length
syscall
# write to file
###############################################################
# Close the file
li
$v0, 16
# system call for close file
move $a0, $s6
# file descriptor to close
syscall
# close file
###############################################################
Fonte: http://courses.missouristate.edu/kenvollmar/mars/help/syscallhelp.html
15
Download