Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Introduccin a la Informtica
Prcticas de Laboratorio de
Introduccin a los
Computadores
Grado en Ingeniera Informtica
Escuela de Ingeniera Informtica
Prlogo .................................................................................... 6
1. Instalando y conociendo el simulador QtSpim .......................... 7
Introduccin .......................................................................... 7
Instalacin del QtSpim ............................................................ 7
Descripcin del Simulador QtSpim ............................................ 8
Cargar programas en QtSpim .............................................. 10
Ejecutar programas en QtSpim ............................................ 10
Depurar programas en QtSpim ............................................ 11
Controlar lo que muestra QtSpim (Opciones de Display) .......... 12
Modificar el contenido de la memoria o de los registros ........... 12
Opciones de simulacin de QtSpim ....................................... 13
Sintaxis del Lenguaje ensamblador del MIPS R2000 .................. 16
Instrucciones .................................................................... 16
Pseudoinstrucciones ........................................................... 17
Directivas ......................................................................... 17
Comentarios ..................................................................... 17
Etiquetas .......................................................................... 18
Problemas propuestos ........................................................... 18
2. Definicin de datos ............................................................ 21
Introduccin ........................................................................ 21
Definicin del rea de datos de un programa ............................ 21
Cmo muestra QtSpim los datos en memoria? ....................... 21
Definicin de palabras ........................................................... 24
Definicin de bytes ............................................................... 26
Definicin de cadenas de caracteres ........................................ 26
Reservas de espacio en memoria ............................................ 27
Alineacin de datos en memoria ............................................. 28
Problemas propuestos ........................................................... 29
3. Carga y almacenamiento de datos........................................ 31
Introduccin ........................................................................ 31
Definicin del rea del cdigo de un programa .......................... 31
Carga de datos inmediatos .................................................... 32
Carga de palabras ................................................................ 33
Carga de bytes..................................................................... 35
Almacenamiento de palabras ................................................. 36
Prlogo
Las prcticas de laboratorio de la asignatura de Introduccin a
Informtica tienen como objetivo el estudio, conocimiento y uso del
lenguaje ensamblador y lenguaje mquina a nivel de programacin.
Para lograr este objetivo se ha elegido centrar las tareas sobre la
arquitectura del procesador MIPS R2000 a travs de su conjunto de
instrucciones. Para ello se han elaborado unas prcticas en las que el
alumno utilizar el lenguaje ensamblador de este procesador y
conocer su funcionamiento mediante el simulador QtSpim.
Las prcticas se han dividido de acuerdo a la temtica que tratan en
siete captulos:
1.
2.
3.
4.
5.
6.
7.
1. Instalando y conociendo el
simulador QtSpim
Introduccin
QtSpim es un simulador que ejecuta programas escritos en lenguaje
ensamblador MIPS32. Adems, muestra el contenido de los registros
y la memoria del procesador. Este simulador lee y ejecuta programas
escritos en lenguaje ensamblador para un procesador MIPS R2000. La
arquitectura de este tipo de procesadores es RISC, por lo tanto
simple y regular, lo que la hace fcil de aprender y entender. Para
simplificar el proceso de programacin, QtSpim proporciona adems
un depurador de cdigo sencillo y un conjunto reducido de servicios
del sistema operativo. El simulador no ejecuta programas binarios en
lenguaje mquina, es decir, programas que ya han sido compilados.
QtSpim implementa la mayor parte del repertorio de instrucciones
extendido MIPS32. No implementa las comparaciones en coma
flotante y los modos de redondeo, ni tampoco las tablas de pginas
del sistema de memoria. La arquitectura MIPS posee diversas
variantes que difieren entre s (por ejemplo, la arquitectura MIPS64
soporta tanto nmeros enteros como direcciones de 64 bits) lo que
significa que QtSpim no ejecuta los programas de todos los tipos de
procesadores MIPS.
10
11
Controlar
Display)
de la barra de herramientas.
lo
que
muestra
QtSpim
(Opciones
de
12
13
14
15
Instrucciones
Son cada una de las operaciones bsicas que el procesador es capaz
de ejecutar sobre unos datos determinados. Las instrucciones pueden
clasificarse de acuerdo al tipo de operacin que realizan:
16
Pseudoinstrucciones
Especifican operaciones complejas que el programa debe realizar,
pero que no se corresponden con instrucciones que el procesador
incluya en su repertorio. Por lo tanto, no tienen una traduccin
directa al lenguaje mquina que el procesador es capaz de ejecutar.
El ensamblador sustituye cada una de las pseudoinstrucciones
especificadas en el programa por el conjunto de instrucciones que
realizan una funcin equivalente. El uso de pseudoinstrucciones hace
que la programacin en lenguaje ensamblador sea un proceso ms
sencillo de realizar y que el cdigo que se genere sea ms fcil de
entender.
Directivas
Son sentencias que no especifican operaciones del programa, sino
que indican al ensamblador cmo debe hacer el proceso de
ensamblaje del programa. La sintaxis de las directivas est formada
por un punto (.) y una palabra reservada que indica la accin a
realizar. Adems, pueden incluir algn parmetro adicional necesario
para llevar a cabo la accin requerida.
Un ejemplo de directiva sera:
.data 0x10010000
Comentarios
Dan una explicacin sobre la instruccin, pseudoinstruccin o
directiva a la que acompaan. Tambin pueden existir sentencias que
estn compuestas slo por comentarios, que dan una explicacin
genrica. Los comentarios son de una importancia fundamental en la
programacin en lenguaje ensamblador puesto que permiten realizar
una mejor comprensin de los pasos que se siguen a lo largo del
programa. Para indicar que comienza un comentario se debe utilizar
el carcter #, y desde ese carcter en adelante se entiende que lo
que all se incluye es un comentario, as que no debe traducirse a
lenguaje mquina. Por tal motivo el ensamblador ignora durante el
ensamblaje los caracteres que se encuentren despus del smbolo
#.
Un ejemplo de sentencia que incluye un comentario sera:
add $8, $9, $10
17
Etiquetas
Son identificadores que se sitan al principio de una lnea y van
siempre seguidos de dos puntos. Un identificador es una secuencia de
caracteres (alfanumricos, guin bajo _ y punto .) que no
comienzan con un nmero. Las etiquetas sirven para hacer referencia
a la posicin o direccin de memoria del elemento al que acompaan
(una instruccin, una definicin de un dato,..). Las etiquetas se
pueden utilizar dentro de las instrucciones y directivas formando
parte de los operandos que stas necesitan. No pueden utilizarse
como etiquetas las palabras reservadas para las instrucciones y las
directivas.
Un ejemplo de etiqueta sera:
dato1:
.byte 20
Salto de lnea: \n
Tabulador: \t
Comilla: \
Problemas propuestos
1. Dado el siguiente ejemplo de programa ensamblador, indica las
etiquetas, directivas y comentarios que aparecen en el mismo:
.data
dato:
.byte 25
.text
.globl
main:
main
lw $t0, dato($0)
18
.data
dato1:
.word 15
dato2:
.word 20
.text
.globl
main
19
20
2. Definicin de datos
Introduccin
En este captulo se exploran las diversas maneras que existen de
definir datos en el lenguaje ensamblador MIPS32. Para ello es preciso
conocer los tipos de datos habituales:
Definicin
programa
del
rea
de
datos
de
un
21
Sin embargo, en esa figura vemos tambin que la zona de datos del
stack de usario ocupa las direcciones de memoria 0x7ffffa08 a
0x80000000, y su contenido no es 0. En esta zona podemos ver que
en cada fila de datos aparece a la izquierda la direccin ([7ffffa08]
para la primera fila de datos) y a la derecha los datos que estn
almacenados en memoria a partir de esa direccin (en la primera fila
los datos que estn almacenados en memoria son 00000004 7ffffaf5).
En la Figura 7 puede apreciarse con ms detalle la forma en que
22
23
0x78
0x10010000
0x12
0x56
0x10010001
0x34
0x34
0x10010002
0x56
0x12
0x10010003
(a)
0x78
(b)
Definicin de palabras
Una palabra es un tipo de dato de tamao cuatro bytes. La direccin
de una palabra es la del byte menos significativo. Cualquier acceso a
una palabra de memoria supondr leer cuatro bytes: el byte con la
direccin especificada y los tres almacenados en las siguientes
posiciones. Adems, las direcciones de palabra deben estar alineadas
en posiciones mltiplos de cuatro.
24
palabra1:
.word 15
# decimal
palabra2:
.word 0x15
# hexadecimal
.word 15,0x15
# decimal/hexadecimal
25
Definicin de bytes
Para definir bytes en memoria se utiliza la directiva .byte que tiene la
sintaxis siguiente:
etiqueta: .byte valor
.byte
# hexadecimal
.byte
0x10,0x20,0x30,0x40 # hexadecimal
palabra2:
.word
0x10203040
# hexadecimal
26
Ejercicio 5
Crea un fichero con el siguiente cdigo:
.data
cadena:
.ascii "abcde"
octeto:
.byte 0xff
.data
.space 1
# reservo espacio
.byte 0xff
27
byte1:
.byte
0x10
espacio:
.space
byte2:
.byte
0x20
palabra:
.word
10
.byte 0x10
.align
espacio:
.space
byte2:
.byte
0x20
palabra:
.word
10
28
Problemas propuestos
1. Disea un programa ensamblador que reserva espacio para dos
vectores A y B de 20 palabras cada uno a partir de la direccin
0x10000000.
2. Disea un programa ensamblador que realice la siguiente
reserva de espacio en memoria a partir de la direccin
0x10001000:
una palabra
un byte
una palabra alineada en una direccin mltiplo de 4.
3. Disea un programa ensamblador que realice la siguiente
reserva de espacio e inicializacin en memoria a partir de la
direccin por defecto: 3 (palabra), 0x10 (byte), reserve 4 bytes
a partir de una direccin mltiplo de 4, y 20 (byte).
4. Disea un programa ensamblador que defina, en el espacio de
datos, la siguiente cadena de caracteres: Esto es un problema
utilizando
.ascii
.byte
.word
5. Sabiendo que un dato de tipo entero se almacena en una
palabra, disea un programa ensamblador que defina en la
memoria de datos la matriz A formada por elementos de tipo
entero definida como
29
30
3. Carga y almacenamiento de
datos
Introduccin
El tercer captulo est dedicado al estudio de las instrucciones que
permiten realizar movimientos de datos de memoria a los registros y
viceversa. Adems se estudian tambin algunas instrucciones y
pseudoinstrucciones que permiten cargar datos inmediatos en
registros.
En general, las instrucciones que permiten cargar un dato en un
registro (load en ingls) comienzan con la letra l y las instrucciones
que llevan un dato a memoria (store en ingls) comienzan con la
letra s. En este captulo se estudian las siguientes instrucciones y
pseudoinstrucciones:
Acrnimo
Accin
Tipo
lui
li
Load Inmediate
Pseudoinstruccin
la
Load Address
Pseudoinstruccin
lw
Load Word
Instruccin
lh
Load Half
Instruccin
lb
Load Byte
Instruccin
sw
Store Word
Instruccin
Sh
Store Half
Instruccin
sb
Store Byte
Instruccin
31
# zona de instrucciones
32
Ejercicio 2
El ensamblador del MIPS ofrece la posibilidad de cargar una constante
de 32 bits en un registro utilizando la pseudoinstruccin li (load
inmediate).
Crea un fichero con el siguiente cdigo:
.text
main:
# zona de instrucciones
li $s0, 0x12345678
Carga de palabras
La carga de palabras se refiere a la transferencia de palabras de
datos desde memoria a los registros del procesador.
Ejercicio 3
Crea un fichero con el siguiente cdigo:
33
.data
palabra: .word 0x10203040
.text
main:
# zona de instrucciones
lw $s0, palabra($0)
34
Carga de bytes
La carga de bytes se refiere a la transferencia de bytes desde
memoria a los registros del procesador.
Ejercicio 4
Crea un fichero con el siguiente cdigo:
.data #
octeto:
zona de datos
.byte 0xf3
zona de instrucciones
lb $s0, octeto($0)
.byte 0x30
.word 0x10203040
Por qu?
6. Indica cul es el valor del registro s0 si se cambia en "main" la
instruccin existente por la siguiente
main:
lb $s0, octeto+1($0)
35
Almacenamiento de palabras
El almacenamiento de palabras se refiere a la transferencia de
palabras desde los registros del procesador a la memoria.
Ejercicio 5
Crea un fichero con el siguiente cdigo:
.data
palabra1: .word
zona de datos
0x10203040
palabra2: .space 4
palabra3: .word
.text
main:
0xffffffff
zona de instrucciones
lw $s0, palabra1($0)
sw $s0, palabra2($0)
sw $s0, palabra3($0)
Almacenamiento de bytes
El almacenamiento de bytes se refiere a la transferencia de bytes
desde los registros del procesador a la memoria.
Ejercicio 6
Crea un fichero con el siguiente cdigo:
.data #
palabra1: .word
octeto:
0x10203040
.space 2
.text #
main:
zona de datos
zona de instrucciones
lw $s0, palabra1($0)
sb $s0, octeto($0)
36
Problemas propuestos
1. Disea un programa ensamblador que defina en la memoria de
datos el vector de palabras V=(10,20,25,500,3), a partir de la
direccin 0x10000000 y que cargue todos sus componentes en
los registros $s0 al $s4.
2. Disea un programa ensamblador que copie el vector definido
en el problema anterior a partir de la direccin 0x10010000.
3. Disea un programa ensamblador que, dada la palabra
0x10203040, almacenada en una posicin de memoria, la
reorganice en otra posicin de memoria, invirtiendo el orden de
sus bytes.
4. Disea un programa ensamblador que, dada la palabra
0x10203040 definida en memoria, la reorganice en la misma
posicin, intercambiando el orden de sus medias palabras.
Nota: utiliza las instrucciones lh y sh.
5. Disea un programa en ensamblador que inicialice cuatro bytes
a partir de la posicin 0x10010002 a los siguientes valores
0x10, 0x20, 0x30, 0x40, y reserve espacio para una palabra a
partir de la direccin 0x10010010. El programa transferir los
cuatro bytes contenidos a partir de la posicin 0x10010002 a la
direccin 0x10010010.
6. Disea un programa en lenguaje ensamblador que defina los
siguientes bytes en memoria: 0xab, 0xcd, 0xef, 0x10. El
37
38
Servicio
Cdigo
Parmetros
(en $v0)
Imprimir
valor entero
Imprimir
cadena
Leer un
entero
(en $v0)
un
$a0=entero
una
$a0=direccin de la cadena
valor
Resultado
Entero
$a0=direccin de la cadena
$a1= longitud de la cadena
39
main:
li $v0,4
la $a0,dir
#direccin de la cadena
syscall
#llamada al sistema
40
Impresin de enteros
El siguiente paso consiste en imprimir datos de tipo entero en la
pantalla. De esta forma podemos presentar al usuario el resultado
final de los programas que ejecutemos.
Ejercicio 2
Crea un fichero con el siguiente cdigo:
.data
dir:
entero:
.word
.text
main:
li $v0,4
la $a0,dir
#direccin de la cadena
syscall
#llamada al sistema
li $v0,1
li $a0,5
#entero a imprimir
syscall
#llamada al sistema
Lectura de enteros
Esta seccin trata sobre la forma de hacer la lectura de datos de tipo
entero desde el teclado. Esta funcionalidad nos permitir desarrollar
programas ms complejos, que son capaces de pedir datos numricos
al usuario.
Ejercicio 3
Crea un fichero con el siguiente cdigo:
.data
dir:
entero:
.space 4
.text
main:
#direccin de la cadena
41
syscall
#llamada al sistema
#llamada al sistema
buffer:
.space
10
.text
main:
#direccin de la cadena
syscall
#llamada al sistema
li $a1,10
syscall
#llamada al sistema
42
Problemas propuestos
1. Disea un programa ensamblador que pida por la consola dos
enteros A, B y C dando como resultado su suma A+B+C.
Utiliza la instruccin add $rd, $rs, $rt que suma el contenido
de los registros $rs y $rt, dejando el resultado en el registro
$rd.
2. Disea un programa que pida los datos de un usuario por el
teclado y los introduzca en memoria, reservando espacio para
ello. La estructura de la informacin es la siguiente:
Nombre
Cadena de 10 bytes
Apellidos
Cadena de 15 bytes
DNI
Nmero entero
43
44
de
desplazamiento
Operaciones
aritmticas
inmediatos (constantes)
con
datos
.word 2147483647
.text
main:
lw
$t0,numero($0)
addiu $t1,$t0,1
45
Cuestiones
1. Localiza el resultado de la suma efectuada. Comprueba el
resultado.
2. Cambia la instruccin addiu por la instruccin addi. Borra los
valores de la memoria, carga el fichero y ejectalo paso a paso.
Qu ha ocurrido al efectuar el cambio? Por qu?
.word 0x80000000
numero2:
.word 1
numero3:
.word 1
.text
main:
lw
$t0,numero1($0)
lw
$t1,numero2($0)
subu
$t0,$t0,$t1
lw
$t1,numero3($0)
subu
$t0,$t0,$t1
sw
$t0,numero3($0)
en numero3? Es correcto?
2. Se producir algn cambio si las instrucciones subu son
sustituidas por instrucciones sub? Por qu?
46
.word -1
numero2:
.word 16
.space 8
.text
main:
lw
$t0,numero1($0)
lw
$t1,numero2($0)
mult
$t0,$t1
mflo
$t0
mfhi
$t1
sw
$t0,numero2+4($0)
sw
$t1,numero2+8($0)
47
Cuestiones
1. Qu resultado se obtiene despus de realizar la operacin?
Operaciones lgicas
Adems de las operaciones aritmticas, el repertorio de instrucciones
incluye tambin las operaciones lgicas bsicas que permiten trabajar
con los datos a nivel de bit: and, or, xor.
Ejercicio 4
Crea un fichero con el siguiente cdigo:
.data
numero:
.word
0x3ff41
.space 4
.text
main:
lw
$t0,numero($0)
andi
$t1,$t0,0xfffe
sw
$t1,numero+4($0)
48
bits, poniendo los 16 de mayor peso a 0, fijando, por tanto, los bits
del resultado tambin a 0.
Borra los valores de la memoria, carga el fichero y ejectalo.
Cuestiones
1. Modifica el cdigo para obtener, en la siguiente palabra, que los
Operaciones de desplazamiento
Para terminar el captulo se estudian en esta seccin las instrucciones
que permiten realizar desplazamientos aritmticos o lgicos a
izquierda o derecha: sra, srl, sll. En estas instrucciones la primera
letra indica que se trata de un desplazamiento (del ingls shift), la
segunda letra indica el sentido del desplazamiento (del ingls right o
left) y la tercera letra indica si el desplazamiento es aritmtico o
lgico (del ingls arithmetic o logic). As por ejemplo, la instruccin
sra realiza un desplazamiento aritmtico a la derecha del dato
especificado. Ntese que NO EXISTE la instruccin sla, ya que es
equivalente a la instruccin sll. Tambin es importante tener en
cuenta que un dato de 32 bits slo puede ser desplazado 31 veces
seguidas en el mismo sentido.
Ejercicio 5
Crea un fichero con el siguiente cdigo:
.data
numero:
.word
0xffffff41
.text
main:
lw
$t0,numero($0)
sra
$t1,$t0,4
49
izquierda.
Problemas propuestos
1. La instruccin mul (de tipo R) multiplica dos registros y guarda
el resultado en un tercero. Escribe un programa en
ensamblador que utilice la instruccin mul para multiplicar
numero1=0x7fffffff y nmero2=16 y deje el resultado en el
registro $t2. Deja el resultado tambin en algn otro registro?
Qu ocurre al cambiar la instruccin mul en el programa
anterior por la pseudoinstruccin mulo? Qu ocurre al cambiar
la pseudoinstruccin mulo en el programa anterior por la
pseudoinstruccin mulou?
2. La pseudointruccin div divide dos registros y guarda el
resultado en un tercero. Escribe un programa en ensamblador
que utilice la pseudoinstruccin div para dividir numero1=17 y
nmero2=5 y deje el resultado en el registro $t2. Comprueba
excepciones?
Cul?
Qu
ocurre
al
cambiar
la
pseudoinstruccin div en el programa anterior por la
pseudoinstruccin divu? Qu es diferente en el cdigo
generado para las pseudoinstrucciones div y divu?
3. Disea un programa ensamblador que defina el vector de
enteros de dos elementos V=(10,20) en la memoria de datos a
partir de la direccin 0x10000000 y almacene su suma a partir
de la direccin donde acaba el vector.
4. Disea un programa ensamblador que divida los enteros -1215
y 18 almacenados a partir de la direccin 0x10000000 entre el
nmero 5 y que a partir de la direccin 0x10010000 almacene
el cociente de dichas divisiones. Es posible usar ms de una
directiva .data para ubicar la seccin de datos.
5. Pon a cero los bits 3, 7 y 9 del entero 0xABCD12BD
almacenado en memoria a partir de la direccin 0x10000000,
sin modificar el resto de bits.
6. Cambia el valor de los bits 3,7,9 del entero 0xFF0F1235
almacenado en memoria a partir de la direccin 0x10000000,
sin modificar el resto de bits.
50
51
52
5. Estructuras
de
control:
condicionales y bucles
Introduccin
El lenguaje ensamblador no dispone de estructuras de control de flujo
de programa definidas a priori, que permitan decidir entre dos (o
varios) caminos de ejecucin de instrucciones distintos (como por
ejemplo la sentencia if de otros lenguajes de programacin). En
esta prctica se describe cmo implementar algunas de estas
estructuras de control.
En primer lugar se realiza un breve recordatorio de las instrucciones
que dispone el MIPS R2000 a partir de las cuales se llevan a cabo las
implementaciones de estructuras de este tipo. Estas se agrupan en
tres grupos: instrucciones de salto condicional, instrucciones de salto
incondicional e instrucciones de comparacin. Adems se dispone
tambin de pseudoinstrucciones de salto condicional.
53
Instrucciones de comparacin
El ensamblador del MIPS dispone de una instruccin que compara dos
registros, y pone un 1 en un tercer registro si el contenido del
primero es menor que el segundo y pone un 0 si no se cumple esta
condicin. Esta instruccin es slt (set if less than, poner a 1 si menor
que y si no poner un 0) y tiene la siguiente sintaxis:
slt $rd, $rs, $rt
54
Si-
Ejercicio 1
Crea un fichero con el siguiente fragmento de cdigo que implementa
una estructura de control condicional Si-entonces:
.data
dato1:
.word
40
dato2:
.word
30
res:
.space
.text
main:
lw
$t0, dato1($0)
#cargar dato1 en t0
lw
$t1, dato2($0)
#cargar dato2 en t1
#pone a 0 t2
#t3 = t0+t1
Si:
#si t1 = 0 finsi
entonces:
#t0/t1
mflo $t2
#almacenar LO en t2
#t2= t3 + t2
sw
#almacenar en memoria t2
finsi:
$t2, res($0)
55
Si-
Ejercicio 2
Crea un fichero con el siguiente fragmento de cdigo que implementa
una estructura de control condicional Si-entonces:
.data
dato1:
.word
40
dato2:
.word
30
res:
.space
.text
main:
Si:
entonces:
finsi:
lw
$t0, dato1($0)
#cargar dato1 en t0
lw
$t1, dato2($0)
#cargar dato2 en t1
#pone a 0 t2
#t3=t0 + t1
#t0/t1
mflo $t2
#almacenar LO en t2
#t2=t2 + t3
56
sw
$t2, res($0)
#almacenar en memoria t2
dato1=40, dato2=30
dato1=0, dato2=40
dato1=40, dato2=-40
Si-
Ejercicio 3
Crea un fichero con el siguiente fragmento de cdigo que implementa
una estructura de control Si-entonces-sino.
.data
dato1:
.word
30
dato2:
.word
40
res:
.space
.text
main:
lw
$t0,dato1($0)
lw
$t1,dato2($0)
Si:
bge
$t0,$t1,sino
entonces:
sw
$t0, res($0)
finsi
sw
$t1, res($0)
sino:
#almacenar t0 en res
#almacenar t1 en res
finsi:
57
Cuestiones
1. Identifica qu condicin se evala.
2. Qu valor se almacena en res despus de ejecutar el
programa?
3. Si dato1=50 y dato2=0, qu valor se almacena en res
despus de ejecutar el programa? Qu hace entonces el
programa?
4. Identifica en el lenguaje mquina generado por el simulador el
conjunto
de
instrucciones
que
implementan
la
pseudoinstruccin bge.
.word
30
dato2:
.word
40
dato3:
.word
-1
res:
.space
.text
main:
si:
lw
$t1,dato1($0)
#cargar dato1 en t1
lw
$t2,dato2($0)
#cargar dato2 en t2
lw
$t3,dato3($0)
#cargar dato3 en t3
blt
ble
entonces: addi
$t4, $0, 1
#si t3<=t2
saltar a sino
#t4 = 1
finsi
sino:
add
$t4, $0,$0
#t4 = 0
finsi:
sw
$t4, res($0)
#almacenar en memoria t4
58
.word
6,7,8,9,10,-1
res:
.space
.text
main:
para:
la
$t2, vector
#t2 = vector
and
#pone a 0 t3
li
$t0, 1
#carga 1 en t1
li
$t1, 6
bgt
lw
$t4, 0($t2)
# carga un elemento en t4
add
finpara:
addi
$t2, $t2, 4
#suma 4 a t2
addi
$t0, $t0, 1
#resta 1 a t1
para
#saltar a para
sw
$t3, res($0)
#almacena t3 en res
59
n:
.asciiz
"hola"
.align
.space
.text
main:
la
$t0, cadena
#cargar la direccion de
#cadena en t0
mientras:
#poner a 0 t2
lb
$t1, 0($t0)
#almacena un byte en t1
beq
#sumar 1 a t2
#sumar 1 a t0
j mientras
#saltar a mientras
#almacenar t2 en n
60
Problemas propuestos
1. Disea un programa en ensamblador que almacene en memoria
los 3 enteros siguientes (dato1=2, dato2=20 y res=0) y que
reserve 1 byte para almacenar una variable booleana, que se
llamar bool. Implementa el siguiente fragmento de cdigo:
Si dato2<>0 y (resto(dato1/dato2)>0) entonces
res=resto(dato1/dato2)
bool=1
sino
res=-1
bool=0
Finsi
61
62
5. Gestin de Subrutinas
Introduccin
El diseo de un programa que resuelve un determinado problema
puede simplificarse si se plantea adecuadamente la utilizacin de
subrutinas. stas permiten dividir un problema largo y complejo en
subproblemas ms sencillos o mdulos, ms fciles de escribir,
depurar y probar que si se aborda directamente el programa
completo. De esta forma se puede comprobar el funcionamiento
individual de cada rutina y, a continuacin, integrarlas todas en el
programa que constituye el problema global de partida. Otra ventaja
que aporta la utilizacin de subrutinas es que en ocasiones una tarea
aparece varias veces en el mismo programa; si se utilizan subrutinas,
en lugar de repetir el cdigo que implementa esa tarea en los
diferentes puntos, bastar con incluirlo en una subrutina que ser
invocada en el programa tantas veces como sea requerida. Yendo
ms lejos, subproblemas de uso frecuente pueden ser implementados
como rutinas de utilidad (libreras), que podrn ser invocadas desde
diversos mdulos.
Con el fin de dotar de generalidad a una subrutina, sta ha de ser
capaz de resolver un problema ante diferentes datos que se le
proporcionan como parmetros de entrada cuando se le llama. Por
tanto, para una correcta y eficaz utilizacin de las subrutinas es
necesario tener en cuenta, por un lado, la forma en que se realizan
las llamadas y, por otro, el paso de parmetros.
Como paso previo a la realizacin de la prctica se van a realizar
algunos ejercicios sencillos que nos ayuden a entender y prcticar el
manejo de la pila, estructura muy utilizada para una buena gestin
de las subrutinas.
Gestin de la pila
Una pila es una estructura de datos caracterizada porque el ltimo
dato que se almacena es el primero que se obtiene en una lectura.
Para gestionar la pila se necesita un puntero a la ltima posicin
ocupada de la misma, con el fin de conocer dnde se tiene que dejar
el siguiente dato a almacenar, o para saber dnde estn situados los
ltimos datos almacenados en ella. Para evitar problemas, el puntero
de pila siempre debe estar apuntando a una palabra de memoria. Por
precedentes histricos, el segmento de pila siempre "crece" de
direcciones superiores a direcciones inferiores. Las dos operaciones
ms tpicas con esta estructura son:
63
li
$t0,10
li
$t1, 13
#inicializar regs t0 y t1
addi
$sp, $sp, -4
#actualizar el sp
sw
$t0, 0($sp)
#apilar t0
addi
$sp, $sp, -4
#actualizar el sp
sw
$t1, 0($sp)
#apilar t1
64
Por otra parte, el MIPS R2000 dispone de una instruccin que facilita
el retorno de una subrutina. Esta instruccin es jr $ra, instruccin de
salto incondicional que salta a la direccin almacenada en el registro
$ra, que justamente es el registro dnde la instruccin jal ha
almacenado la direccin de retorno cuando se ha hecho el salto a la
subrutina.
Para ejecutar cualquier programa de usuario el simulador QtSpim
hace una llamada a la rutina main mediante la instruccin jal main.
Esta instruccin forma parte del cdigo que aade ste para lanzar a
ejecutar un programa de usuario. Si la etiqueta main no est
declarada en el programa se genera un error. Esta etiqueta deber
siempre estar colocada en la primera instruccin ejecutable de un
programa de usuario. Para que cualquier programa de usuario
termine de ejecutarse correctamente, la ltima instruccin ejecutada
en ste debe ser jr $ra (salto a la direccin almacenada en el
registro $ra), que devuelve el control a la siguiente instruccin desde
donde se lanz la ejecucin del programa de usuario. A partir de este
punto se hace una llamada a una funcin del sistema que termina la
ejecucin correctamente.
Ejercicio 2
El siguiente cdigo es un programa que realiza la suma de dos datos
contenidos en los registros $a0 y $a1.
.text
main:
li
$a0,10
li
$a1,20
add
$v1,$a0,$a1
jr
$ra
65
Cuestiones
1. Cul es el contenido del PC y del registro $ra antes y despus
de ejecutar la instruccin jal main?
2. Cul es el contenido de los registros PC y $ra antes y despus
de ejecutar la instruccin jr $ra?
3. Reinicializa el simulador, carga el programa de nuevo y
ejectalo todo completo. Comprueba que la ejecucin termina
correctamente.
.space
66
.text
main:
subr:
addi
$sp, $sp, -4
sw
$ra,0($sp)
li
$a0,10
li
$a1,2
jal
subr
sw
$v0,suma($0)
lw
$ra, 0($sp)
addi
$sp,$sp,4
jr
$ra
add
$v0, $a0,$a1
jr
$ra
Paso de parmetros
A la hora de implementar una subrutina hay que decidir qu
parmetros se deben pasar a la rutina, dnde se le van pasar y cmo
se le van a pasar. En cuanto al cmo se le pasan los parmetros,
existen dos posibilidades:
67
Pasarlos en registros
Pasarlos en la pila
Ejercicio 4
El siguiente programa implementa la llamada a una subrutina y el
cdigo de la misma, que devuelve una variable booleana que vale 1 si
una determinada variable est dentro de un rango, y 0 en caso
contrario. La subrutina tendr los siguientes parmetros:
Parmetros de entrada:
Parmetros de salida:
rango1:
.word
10
rango2:
.word
50
dato:
.word
12
res:
.space
.text
main:
addi
$sp,$sp,-4
sw
$ra,0($sp)
lw
$a0,rango1($0) #a0=rango1
lw
$a1,rango2($0) #a1=rango2
lw
$a2,dato($0)
#a2=dato
jal
subr
#saltar a subr
sb
$v0,res($0)
#res=v0
#apilar ra
68
lw
$ra,0($sp)
addi
$sp,$sp,4
#desapilar ra
jr
$ra
blt
$a2,$a0,sino
bgt
$a2,$a1,sino
addi
$v0,$0,1
#v0=1
finsi
#saltar a finsi
sino:
add
$v0,$0,$0
#v0=0
finsi:
jr
$ra
#retornar
subr:
entonces:
69
70
.word
vec1:
.word
1,0,0,2
nul1:
.space
.text
#en primer lugar se inicializan los registros s0, s1, s2 y fp
71
main:
ret:
subr:
li
$s0,1
li
$s1,2
li
$s2,3
li
$fp,4
addi
$sp,$sp,-4
sw
$ra,0($sp)
addi
$sp,$sp,-8
lw
$t0,n1($0)
sw
$t0,4($sp)
la
$t0,vec1
sw
$t0,0($sp)
jal
subr
addi
$sp,$sp,8
sw
$v0,nul1($0)
lw
$ra,0($sp)
addi
$sp,$sp,4
jr
$ra
addi
$sp,$sp,-16
sw
$fp,12($sp)
addi
$fp,$sp,12
sw
$s0,-4($fp)
sw
$s1,-8($fp)
sw
$s2,-12($fp)
lw
$s0,4($fp)
lw
$s1,8($fp)
and
$v0,$v0,$0
72
bucle:
finsi:
beq
$s1,$0,finb
lw
$s2,0($S0)
bne
$s2,$0,finsi
addi
$v0,$v0,1
addi
$s0,$s0,4
# s0 = s0+4
addi
$s1,$s1,-1
# s1=s1-1
j bucle
finb:
# si s1 = 0 saltar a finb
# cargar s2=Mem(s0)
#si s3<>0 saltar a finsi
#v0=s2
#saltar a bucle
lw
$s0,-4($fp)
lw
$s1,-8($fp)
lw
$s2,-12($fp)
addi
$sp,$fp,0
lw
$fp,0($sp)
addi
$sp,$sp,4
jr
$ra
Cuestiones
1. Identifica la instruccin o conjunto de instrucciones que realizan
las siguientes acciones en el programa que hace la llamada a la
subrutina subr:
a. Carga de parmetros en la pila.
b. Llamada a la subrutina.
c. Limpieza de la pila de los parmetros pasados a travs de
ella.
d. Almacenamiento del resultado.
2. Identifica la instruccin o conjunto de instrucciones que realizan
las siguientes acciones en la subrutina subr:
a. Actualizacin del bloque de activacin de la subrutina.
b. Lectura de los parmetros de la pila y procesamiento de
los mismos.
c. Carga del resultado en $v0.
d. Desapilar bloque de activacin los registros apilados y
eliminar las variables locales. Actualizar el puntero de
pila.
e. Retorno al programa que ha hecho la llamada.
3. Ejecuta paso a paso el programa anterior y dibuja la situacin
del bloque de activacin y de los registros $s0, $s1, $s2, $fp,
$sp, $ra y PC en cada una de las siguientes situaciones:
Programa que hace la llamada a la subrutina subr, hasta el
momento que hace la llamada:
73
Problemas propuestos
1. Implementa un programa que almacene en memoria la cadena
de caracteres espumoso. El programa debe invertir esta
cadena, almacenando la cadena resultante en las mismas
posiciones de memoria que la original. (Sugerencia para
realizar el ejercicio: Apila los elementos de la tira en la pila y, a
continuacin, desaplaos y almacnalos en el mismo orden que
se extraen).
2. Partiendo del cdigo original del ejercicio 3 de esta prctica,
aade el cdigo necesario para que la subrutina subr calcule la
operacin $v0=$a0/$a1. Esta divisin slo se realizar si ambos
operandos son mayores que 0. La comprobacin se realizar en
una segunda subrutina llamada comp que almacenar en $v0
un 1, si los datos contenidos en los registros $a0 y $a1 son
mayores que 0, y un 0 en caso contrario. La llamada a esta
segunda subrutina se realizar desde la subrutina subr, y sta
almacenar en $v0 el cociente de la divisin, si sta se realiza y
un -1 en caso contrario.
74
75
76