Ejemplo Ejemplo

Anuncio
01/03/2012
1
Ejemplo
2

Escriba un programa que realice las siguientes
operaciones
Lea 10 números
Los almacene en memoria
 Proporcione la suma de los 10 números


PROCEDIMIENTOS
UNIDAD 3
PRIMAVERA 2012
.data
array:
.space 40
str1:
.asciiz “Proporcione un numero: ”
str2:
.asciiz “Las suma total es : ”
Arquitectura de computadoras
.text
.globl main
main:
loop:
imprime: li
li
$s1,0
# Inicializa suma = 0
li
$t0, 0
# inicializa el contador
la
la
$s0, array
$v0,4
# inicializa el apuntador
syscall
slti $t1, $t0, 10
# verifica si t0 < 10
li
beq $t1,$zero, imprime
# si t0 >= 10 sale del ciclo
add $a0, $zero, $s1
li
$v0,4
# Imprime la cadena 1
syscall
la
$a0,str1
li
syscall
li
$v0,5
# Imprime la cadena 2
$a0,str2
$v0,1
$v0, 10
# Muestra el resultado
# transfiere el resultado a a0
# Termina el programa
syscall
# Lee un numero entero
syscall
add $s1,$s1,$v0
# suma = suma + numero
sw $v0,0($s0)
# almacena el numero
addi $s0,$s0,4
# incrementa el apuntador
addi $t0,$t0,1
# incrementa el contador
j
3
loop
4
.text
Ejemplo
.globl main
main:
5

Escribe un programa que realice las siguientes operaciones

Lea 10 números

Almacene los números en memoria

Verifique cuantos números son mayores que 20

Muestra todos los números que son mayores de 20
loop:
.data
array:
.space 40
numeros:
.space 40
str1:
.asciiz “Proporcione un numero: ”
str2:
.asciiz “La cantidad de numeros mayores de 20 es: “
str3:
.asciiz “Los numeros mayores de 20 son: ”
str4:
.asciiz “\n”
str5:
.asciiz “, “
li
$s2,0
# Inicializa contador de numeros
li
$t0, 0
# inicializa el contador
li
$s3, 20
# almacena la constante 20
la
$s0, array
# inicializa el apuntador
la
$s1, numeros
# inicializa el apuntador a > 20
slti $t1, $t0, 10
# verifica si t0 < 10
beq $t1,$zero, result
# si t0 >= 10 sale del ciclo
li
$v0,4
# Imprime la cadena 1
la
$a0,str1
syscall
li
$v0,5
# Lee un numero entero
syscall
6
sw $v0,0($s0)
# almacena el numero
slt
# compara el numero con 20
$t2, $s3, $v0
1
01/03/2012
update:
result:
beq $t2,$zero,update
# lee le siguiente numero
addi $s2,$s2,1
# incrementa el contador de num
sw
# almacena los numeros mayores
$v0,0($s1)
addi $s1,$s1,4
# incrementa el apuntador a num
addi $s0,$s0,4
# incrementa el apuntador
addi $t0,$t0,1
# incrementa el contador
j
loop
li
$v0,4
la
$a0,str2
$v0,1
add $a0, $zero, $s2
$v0,4
la
$a0,str4
$t0, 0
# inicializa el contador
la
$s1, numeros
# inicializa el apuntador a > 20
lw
$a0,0($s1)
li
$v0,1
li
$v0,4
# Muestra el resultado
la
$a0,str5
# transfiere el resultado a a0
syscall
# Imprime una alimento de linea
exit:
8
addi $t0,$t0,1
# incrementa el contador
addi $s1,$s1,4
# incrementa el apuntador
j
imprime
li
$v0, 10
.globl main
Escriba un programa que realice las siguientes
operaciones
li
$t0, 0
# inicializa el contador
li
$v0,4
# Imprime la cadena 1
la
$a0,str1
syscall
Lea una cadena
 Proporcione la longitud de la cadena

li
$v0,8
la
$a0,cadena
li
$a1,50
la
$s0,cadena
lb
$s1,0($s0)
cadena:
.space 50
str1:
.asciiz “Proporcione una cadena: ”
str2:
.asciiz “La longitud de la cadena es : “
addi $s0,$s0,1
str3:
.asciiz “\n”
bne
loop:
addi $t0,$t0,1
$s1,$zero, loop
addi $t0,$t0,-2
# Imprime la cadena 2
syscall
li
$v0,1
# Obtén el carácter de la cadena
# incrementa el contador
#Compruebo si es el final de la cadena
# resto 2 uno por el alimento de línea (enter)
# otro por el uno de mas para terminar el ciclo
10
$a0,str2
# Lee la cadena
syscall
.data
$v0,4
# Imprime la cadena 1
syscall
main:
la
# si t0 >= 10 sale del ciclo
.text
9
li
# verifica si t0 < s2
syscall
Ejemplo

# Imprime la cadena 3
li
beq $t1,$zero, exit
# Imprime la cadena 2
syscall
7
$a0,str3
imprime: slt $t1, $t0, $s2
syscall
li
$v0,4
la
syscall
syscall
li
li
Ejercicio
12
# Imprime la longitud
syscall
Escriba un programa que realice las siguientes
acciones:
li

add $a0,$zero,$t0
$v0,10
syscall


Lea una cadena
Imprima la cadena en orden inverso
11
2
01/03/2012
Solución
13
longitud:
.space 50
reves:
.space 50
str1:
.asciiz “Proporcione una cadena: ”
bne
$s1,$zero, longitud
addi $t0,$t0,-1
li
.asciiz “La cadena al reves es: “
# Obtén el carácter de la cadena
# incrementa el contador
#Compruebo si es el final de la cadena
# ajustar la longitud
$t1,0
addi $s0,$s0,-2
.text
imprime:
.globl main
la
$s2,reves
slt
$t2, $t1, $t0
# incializa el apuntador a la cadena reves
li
$t0, 0
# inicializa el contador
beq $t2, $zero, exit
li
$v0,4
# Imprime la cadena 1
lb
$s1,0($s0)
# obtén el último carácter
la
$a0,str1
sb
$s1,0($s2)
# almacenalo al principio de la cadena reves
syscall
li
$v0,8
la
$a0,cadena
li
$a1,50
# Lee la cadena
sb $zero,0($s2)
# almacena el fin de cadena
li
$v0,4
# Imprime la cadena 2
la
$a0,str2
$v0,4
ls
$a0,reves
# incrementa el apuntador a la cadena reves
addi $t1,$t1,1
# incrementa el contador
imprime
Procedimientos

# Imprime la cadena al reves
Convenciones de la llamada a procedimientos
Convenciones seguidas por software pero no
reforzadas por hardware
 Es una serie de reglas que nos indican que registros
usar para el paso de parámetros
 La convención usada es la que el compilador gcc
emplea. Otros compiladores pueden emplear reglas un
poco diferentes
 Las letras de los registros representan el propósito de
los registros dentro de la convención

syscall
li
# decrementa el apuntador a la cadena original
addi $s2,$s2,1
16
syscall
li
addi $s0,$s0,-1
j
14
syscall
exit:
$s1,0($s0)
addi $s0,$s0,1
cadena:
main:
$s0,cadena
lb
addi $t0,$t0,1
.data
str2:
la
$v0,10
syscall
15
17
Convenciones de la llamada a
procedimientos


Los registros $at, $k0 y $k1 son reservados para el
ensamblador y el sistema operativo. Ninguno debe ser
empleado en un programa
18
Convenciones de la llamada a
procedimientos

Registros $a0 – $a3 son usados para enviar los
primeros 4 argumentos al procedimiento. (En caso de
existir mas de 4 argumentos, se usará el stack para la
transmisión de los argumentos restantes)



Los registros $t0 – $t9 son registros temporales cuyos
valores no deben ser preservados durante las llamadas
a procedimiento
Registros $s0 a $s7 son registros cuyos valores
deben ser preservados durante llamadas a los
procedimientos.

En caso de usar registros $s0 – $s7 dentro de un
registro, entonces sus valores deberán ser guardados
en el stack antes de ser usados
Registro $sp es el apuntador al stack
Registro $ra guarda la dirección de regreso de un
procedimiento
3
01/03/2012
Procedimientos
19
Llamadas a Procedimientos
20

Para llamar a un procedimiento se deben realizar las
siguientes acciones

main:
syscall
Pasar los valores por medio de los registros $a0 -$a3
 En caso de ser necesario, el resto de los argumentos deben ser
colocados en el stack


Guardar registros $t0-$t9 y $a0-$a3


Esto solo se realiza si el programa principal usará estos valores
después de la llamada al procedimiento
Ejecutar la instrucción jal

Esta instrucción es un salto incondicional que realiza la llamada a
la subrutina
li $v0,4
la $a0,str
Pasar los argumentos
Realiza la llamada
a la subrutina y
guarda la dirección
de regreso en el
registro $ra
exit:
imprime:
slt
$t2, $t1, $t0
beq $t2, $zero, exit
lb
$t3,0($t4)
sb
$t3,0($t5)
add $a0,$zero,$t0
addi $t4,$t4,-1
la
$a1,array
addi $t5,$t5,0
jal
imprime
addi $t1,$t1,1
exit:
li
j
imprime
jr
$ra
$v0,10
syscall
Pila (Stack)
21
Marco de Llamada al Procedimiento
22

La pila es un sección de memoria reservada para:

Intercambio de argumentos entre procedimientos
 Guardar temporalmente valores de registros
 Guardar valores de registros específicos durante
interrupciones


Los procedimientos requiere de una sección del
stack reservada para cada procedimiento que es
llamada Marco de Llamada al Procedimiento
Esta sección contiene:
La pila consiste en una serie de locaciones de
memoria manejadas como (LIFO) Last-input-FirstOutput. El primero en entrar es el ultimo en salir
El valor de los argumentos que son pasados al
procedimiento
 El valor de los registros que no se deben modificar
 Proveer espacio para las variables locales de un
procedimiento
Marco de Llamada al Procedimiento
Marco de Llamada al Procedimiento


23
24

El procedimiento (función) debe establecer el marco por
medio de las siguientes acciones:

Reservar memoria para el marco por medio de restar el
tamaño deseado del marco del valor del apuntador al
stack ($sp)
sp  sp  frame _ size

Guardar los registros
$fp
$ra solo si la función llamara a otra función
 $s0 - $s7 solo si estos registros son usados dentro de la función





Este marco esta delimitado por el frame pointer
$fp y el stack pointer $sp.
$sp marca el final del marco mientras que $fp
marca el inicio del marco
El ultimo paso para establecer el marco del
procedimiento es establecer el valor de $fp
fp  sp   frame _ size  4
4
01/03/2012
Procedimiento
Ejemplo
25
26

El procedimiento debe ejecutar los siguientes pasos:

Si el procedimiento es una función que regresa un valor,
entonces el valor debe ser almacenado en el registro
$v0
 Restaurar todos los registros salvados antes del
procedimiento
 Regresar el valor original de registro $sp
 Regresar a la dirección de retorno por medio de la
instrucción jr $ra


Los argumentos del procedimiento son:



$a0 tendrá la cantidad de números que deberán ser leídos
$a1 la dirección de memoria donde se almacenaran los números
Un procedimiento llamado WRITE que lea N números de
memoria y los imprima en pantalla

Los argumentos del procedimiento son:


$a0 tendrá la cantidad de números que serán impresos
$a1 la dirección de memoria donde se encuentran almacenados los
números
# Función write
# Esta función leerá N números almacenados en memoria y los desplegara en pantalla
# Argumentos: a0 --- cantidad de números
#
a1 --- dirección donde se encuentran los números
#
a2 --- dirección de la cadena de separación entre números
Write
27
28
write:
# Función read
# Esta función leerá N números y los almacenados en memoria
# Argumentos: a0 --- cantidad de números
#
a1 --- dirección donde se almacenaran los números
loop:
Un procedimiento llamado READ que lea N números y los
almacene en memoria

Read
read:
Realice un programa que utilice dos procedimientos que
hagan los siguiente
li
loop:
# inicializa el contador
# pasa el valor de a0 a t2
stl
# compara si t0 < t2
$t1,$t0,$t2
# inicializa el contador
beq $t1,$zero, exit
add $t2,$zero,$a0
# pasa el valor de a0 a t2
lw
$a0,0($a1)
# obtiene el número de memoria
stl
# compara si t0 < t2
li
$v0, 1
# imprimo el número en pantalla
beq $t1,$zero, exit
# si la condición no se cumple se sale
syscall
li
$v0, 5
# lee un entero
# imprime la cadena separador
$v0,0($a1)
# almacena el número en memoria
li
$v0,4
add $a0,$a2,$zero
syscall
addi $a1,$a1,4
# actualizo apuntador
addi $t0, $t0,1
# incremento contador
j
loop
# regreso a probar condición
jr
$ra
li
$t0, 0
$t1,$t0,$t2
syscall
sw
exit:
$t0, 0
add $t2,$zero,$a0
addi $a1,$a1, 4
# actualizo apuntador
addi $t0, $t0, 1
# incremento contador
j
loop
# regreso a probar condición
jr
$ra
exit:
Programa principal
li
$v0, 4
# imprime la cadena 1
la
$a0,str1
Programa
principal# para pedir los números
syscall
li
$a0,10
# pasa los argumentos, cantidad
.data
la
$a1,array
# y dirección
array:
.space 40
jal
read
# llama al procedimiento
str1:
.asciiz “ Proporciona 10 numeros”
str2:
.asciiz “Los numeros fueron:”
# imprime la cadena 2
# los números fueron
str3:
.asciiz “, “
li
$v0, 4
la
$a0,str2
syscall
li
$a0,10
# pasa los argumentos, cantidad,
la
$a1,array
# dirección y cadena de separación
la
$a2,str3
29
30
.text
.globl main
main:
subu $sp,$sp,32
sw
$ra, 20($sp)
sw
$fp, 16($sp)
addiu $fp, $sp,28
# define le marco del programa
jal
write
# llama al procedimiento
lw
$ra,20(sp)
# restablece el stack
lw
$fp,16(sp)
addiu $sp,$sp,32
jr
$ra
# regresa al sistema operativo
5
01/03/2012
# Función length
# Esta función determina la longitud de una cadena
# Argumentos: a0 --- dirección inicial de la cadena
Ejemplo
length:
31

Realice un programa que utilice los siguientes
procedimientos

argumentos del procedimiento son:

longitud:
$a0 la dirección inicial de la cadena

min2may, cambie las letras minúsculas a mayúsculas
 Los
argumentos del procedimiento son:

$sp,$sp,32
sw
$fp, 20($sp)
sw
$s0, 16($sp)
# define le marco de la función
addiu $fp, $sp,28
Length, determine la longitud de una cadena
 Los
subu
$a0 dirección inicial de la cadena
add
$s0,$a0,$zero
li
$v0,0
lb
$t1,0($s0)
# Obtén el carácter de la cadena
addi
$v0,$v0,1
# incrementa el contador
addi
$s0,$s0,1
bne
$t1,$zero, longitud
#Compruebo si es el final de la cadena
addi
$v0,$v0,-2
# ajustar la longitud
lw
$s0,16(sp)
lw
$fp,20($sp)
addiu $sp,$sp,32
jr
32
for:
Función min2may
33
# Función min2may
# Esta cambia las letras minúsculas en mayúsculas
# Argumentos: a0 --- dirección inicial de la cadena
min2may:
subu
$sp,$sp,32
sw
$fp, 20($sp)
sw
sw
$s0, 16($sp)
$ra, 12($sp)
# define le marco de la función
update:
addiu $fp, $sp,28
$ra
slt
$t2,$t0,$v0
# compara si el contador es menor que v0
beq
$t2,$zero,exit
# Obtén el carácter de la cadena
lb
$t1,0($s0)
# incrementa el contador
slti
$t2,$t1,123
# Es una letra menor que „z‟
beq
$t2,$zero, update
slt
$t2,$t4, t1
beq
$t2,$zero, update
addi
$t1,$t1,-32
# resta -32 para obtener letras mayusculas
sb
$t1,0($s0)
# almacena el resultado
addi
$t0,$t0,1
# incrementa el contador
addi
$s0,$s0,1
# actualiza el apuntador
j
for
add
jal
$s0,$a0,$zero
length
lw
$ra,12(sp)
#obten la longitud de la cadena en v0
lw
$s0,16(sp)
li
$t0, 0
# inicializa contador
lw
$fp,20($sp)
# Es una letra mayor que „a‟
addiu $sp,$sp,32
34
Programa principal
jr
$ra
li
$v0, 4
# imprime la cadena 1
# lee la cadena
la
$a0,str1
Programa
principal# para pedir la cadena
syscall
li
$v0,8
.data
la
$a0, cadena
cadena:
.space 50
li
$a1,50
str1:
.asciiz “ Proporciona una cadena”
syscall
str2:
.asciiz “La cadena en mayusculas es :”
la
$a0, cadena
str3:
.asciiz “, “
jal
min2may
.text
li
$v0, 4
la
$a0,str2
syscall
# imprime la cadena 2
li
$v0, 4
la
$a0,cadena
syscall
# imprime la leída en mayúsculas
lw
$ra,20(sp)
# restablece el stack
lw
$fp,16(sp)
35
36
.globl main
main:
subu $sp,$sp,32
sw
$ra, 20($sp)
sw
$fp, 16($sp)
addiu $fp, $sp,28
# define le marco del programa
addiu $sp,$sp,32
jr
$ra
# regresa al sistema operativo
6
Descargar