Sei sulla pagina 1di 76

Universidad de Las Palmas de Gran Canaria

Departamento de Informtica y Sistemas

Introduccin a la Informtica
Prcticas de Laboratorio de
Introduccin a los
Computadores
Grado en Ingeniera Informtica
Escuela de Ingeniera Informtica

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Almacenamiento de bytes ...................................................... 36


Problemas propuestos ........................................................... 37
4. Interfaz del usuario con el programa .................................... 39
Introduccin ........................................................................ 39
Impresin de una cadena de caracteres ................................... 40
Impresin de enteros ............................................................ 41
Lectura de enteros................................................................ 41
Lectura de cadena de caracteres............................................. 42
Problemas propuestos ........................................................... 43
5. Las operaciones aritmticas y lgicas ................................... 45
Introduccin ........................................................................ 45
Operaciones aritmticas con datos inmediatos (constantes)........ 45
Operaciones aritmticas con datos en memoria ........................ 46
Multiplicacin y divisin con datos en memoria ......................... 47
Operaciones lgicas .............................................................. 48
Operaciones de desplazamiento .............................................. 49
Problemas propuestos ........................................................... 50
5. Estructuras de control: condicionales y bucles ....................... 53
Introduccin ........................................................................ 53
Instrucciones de salto condicional ........................................ 53
Instrucciones de salto incondicional ...................................... 54
Instrucciones de comparacin ............................................. 54
Pseudoinstrucciones de salto condicional ............................... 54
Estructura de control condicional Si-entonces con condicin simple
......................................................................................... 55
Estructura de control condicional Si-entonces con condicin
compuesta .......................................................................... 56
Estructura de control condicional Si-entonces-sino con condicin
simple ................................................................................ 57
Estructura de control condicional Si-entonces-sino con condicin
compuesta .......................................................................... 58
Estructura de control repetitiva para ....................................... 59
Estructura de control repetitiva mientras ................................. 60
Problemas propuestos ........................................................... 61
5. Gestin de Subrutinas ........................................................ 63
Introduccin ........................................................................ 63

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Gestin de la pila ................................................................. 63


Llamada y retorno de una subrutina ........................................ 65
Llamadas anidadas de subrutinas ........................................... 66
Paso de parmetros .............................................................. 67
Bloque de activacin de una subrutina ..................................... 69
Problemas propuestos ........................................................... 74

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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.

Instalando y conociendo el simulador QtSpim


Definicin de datos
Carga y almacenamiento de datos
Interfaz del usuario con el programa
Las operaciones aritmticas y lgicas
Estructuras de control: condicionales y bucles
Gestin de subrutinas

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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.

Instalacin del QtSpim


Para realizar la instalacin del QtSpim basta con acceder a la
direccin http://spimsimulator.sourceforge.net/ y descargar la
versin adecuada a la mquina donde se vaya a realizar la instalacin
(Mac OS X, Linux o Windows).
En el caso de Windows los pasos son los siguientes:
1. La
descarga
de
QtSpim
genera
el
archivo
QtSpim_9.1.4_Windows.zip (para la versin 9.1.4 de QtSpim).
2. A continuacin se hace doble click sobre este archivo, lo que
provoca que se abra una ventana del descompresor que est
instalado en la mquina (Winzip, WinRar, 7Zip,).
3. Se realiza entonces doble click sobre el archivo setup.exe y se
siguen las instrucciones del instalador.
4. Una vez concluida la instalacin se genera un nuevo icono
denominado QtSpim en la opcin Todos los programas del
men Inicio. Al ejecutar este icono se inicia la ejecucin del
QtSpim.

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Descripcin del Simulador QtSpim


Cuando se ejecuta QtSpim se abre una ventana que contiene lo que
se muestra en la Figura 1. Dependiendo de la mquina en la que se
est ejecutando QtSpim (Mac OS X, Linux o Windows) la apariencia
puede ser ligeramente diferente, aunque tanto los mens como los
botones estn ubicados en la misma posicin y realizan la misma
funcin.

Figura 1: Aspecto general del QtSpim.

En la ventana principal de QtSpim se pueden apreciar las barras


habituales de mens y de herramientas, y tres zonas ms:
1. El panel de la parte izquierda de la ventana principal muestra
los registros del procesador. Pueden mostrarse los registros de
aritmtica entera o de coma flotante. Para seleccionar unos u
otros debes hacer click en la pestaa adecuada de la parte
superior del panel (FP Regs Int Regs).

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

En la pestaa Int Regs aparece el nombre de los registros


enteros, R0 a R31, con sus correspondientes alias entre
parntesis, as como su contenido. Aparecen tambin los
registros de control PC, EPC, Cause, BadVAddr, Status, y los
registros especiales HI y LO.
En la pestaa FP Regs aparecen los registros de coma
flotante de simple y doble precisin, FG0 a FG31 y FP0 a
FP30, y los registros de control y estado FIR, FCSR, FCCR y
FEXR.
2. El panel de la parte derecha muestra el segmento de texto que
contiene tanto las instrucciones como los datos. Para elegir
entre el cdigo o los datos debes hacer click en la pestaa
adecuada de la parte superior del panel (Text Data).
En la pestaa Text se pueden ver las instrucciones del
programa. Para cada instruccin se muestra la siguiente
informacin: En primer lugar la direccin de memoria dnde
est almacenada la instruccin (0x00400000 para la primera
instruccin mostrada). A continuacin la instruccin codificada
en lenguaje mquina (0x8fa40000 para la primera instruccin).
Luego la instruccin en lenguaje ensamblador (lw $4, 0($29)
siguiendo con el ejemplo de la primera instruccin), y por
ltimo la instruccin tal cual est escrita en el programa del
usuario, incluyendo el nmero de lnea donde se encuentra la
instruccin y los comentarios (183: lw $a0, 0($sp) # argc para
la primera instruccin). Antes de que se cargue ningn
programa aparecen una serie de instrucciones, introducidas por
el simulador para lanzar adecuadamente la ejecucin de
nuestro cdigo.
En la pestaa Datos aparecen los datos almacenados en las
zonas de memoria de datos del usuario (a partir de la direccin
0x10000000 y hasta la direccin 0x10040000), la pila del usuario
(el puntero de pila, registro sp, se encuentra cargado con la
direccin
0x7ffffa40,
y
sta
crece
hacia
direcciones
decrecientes) y los datos del ncleo del simulador (en el rango
de direcciones 0x90000000 a 0x90010000).
3. El panel de la parte inferior es la ventana de mensajes donde el
QtSpim va proporcionando informacin sobre los pasos que va
realizando.
Todos los paneles del QtSpim son desacoplables, lo que significa que
puedes hacer click en la parte superior de cada panel y arrastrarlo
fuera de la ventana principal del QtSpim para ponerlo en cualquier
otra parte de tu escritorio.

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Adems, al ejecutar QtSpim se abre tambin otra ventana,


denominada Console donde se realizan las entradas y salidas del
programa simulado. Puedes abrir esta ventana directamente
marcando la opcin Console del men Window.

Cargar programas en QtSpim


Los programas que se quieran simular en QtSpim deben estar
almacenados en un archivo. Los archivos que contienen cdigo en
lenguaje ensamblador normalmente tienen extensin .s, como por
ejemplo programa.s. Los ficheros de entrada a QtSpim son de tipo
texto ASCII, que incluyen las instrucciones en lenguaje ensamblador
del programa que se desea simular.
Es importante remarcar que QtSpim no proporciona un entorno de
edicin de programas, lo que significa que el programa debe editarse
con otro programa (tipo Block de notas o similar) para luego ser
cargado y simulado en el QtSpim. Adems es preciso tener en cuenta
que los programas deben crearse en formato de texto plano que no
contenga informacin adicional, como tipos de letras, formatos de
pgina y prrafo, etc, por lo que editores como el Microsoft Word no
son adecuados para la edicin de los programas en lenguaje
ensamblador.
Una vez creado el programa, para cargarlo en QtSpim accedemos al
men File y seleccionamos Load File (o bien directamente con el
botn
de la barra de herramientas) con lo que aparecer un
cuadro de dilogo donde se puede seleccionar el fichero que se quiere
abrir. Una vez abierto, el panel de instrucciones mostrar las
instrucciones y los datos de tu programa.
Otro comando muy til del men File es Reinitialize and Load File
(o directamente el botn
de la barra de herramientas). Este
comando elimina todos los cambios realizados por el programa,
incluyendo borrar de la memoria todas sus instrucciones, y despus
vuelve a cargar el ltimo archivo. Este comando es til cuando se
est realizando la depuracin de un programa, ya que puedes
modificar el programa que ests ejecutando y hacer una prueba
rpida para comprobar si los cambios son correctos sin necesidad de
cerrar y volver a abrir QtSpim.

Ejecutar programas en QtSpim


Para comenzar la ejecucin de un programa en QtSpim, una vez ste
ha sido cargado, debes seleccionar la opcin Run/Continue en el
men Simulator, o directamente el botn
de la barra de
herramientas o con la tecla F5. Entonces el programa se ejecutar
hasta que finalice o hasta que encuentre un error. En cualquier caso

10

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

podrs ver los cambios realizados por tu programa inspeccionando los


paneles de registros y de datos en memoria. Adems, si el programa
incluye operaciones de lectura o escritura desde el terminal, QtSpim
abre una ventana independiente llamada Console, a travs de la cual
se realiza la entrada y salida del programa.
Para parar la ejecucin de un programa que se est ejecutando debes
seleccionar la opcin Pause del men Simulator, o directamente el
botn
de la barra de herramientas. Este comando te permite parar
la ejecucin y comprobar si la ejecucin es correcta hasta ese
momento. Posteriormente puedes reanudar la ejecucin del programa
con la opcin Run/Continue del men Simulator, o bien con la
opcin Single Step del mismo men, o directamente con el botn
de la barra de herramientas o con la tecla F10.
Si por el contrario deseas que la ejecucin del programa pare por
completo debes seleccionar la opcin Stop del men Simulator, o
directamente el botn
de la barra de herramientas. Una vez
realizada la parada del programa, si seleccionas Run/Continue
comenzars a ejecutar el programa de nuevo desde el principio, en
lugar de continuar por donde iba.

Depurar programas en QtSpim


Si el programa no funciona correctamente debers realizar un
proceso de depuracin que consiste en averiguar qu parte es
incorrecta, y corregirla. La forma ms sencilla de hacer la depuracin
de tu programa es ejecutar las instrucciones de una en una,
comprobando que cada instruccin hace lo que esperabas que hiciera.
Este comando de depuracin paso a paso se encuentra tambin
dentro del men Simulator, en la opcin Single Step, o
directamente con el botn
tecla F10.

de la barra de herramientas o con la

En otros casos la forma de depurar un programa requiere de un


proceso algo ms complejo, como por ejemplo, dejar que el
programa se ejecute todo seguido hasta llegar a un punto y despus
ejecutar paso a paso. En este caso, ejecutar paso a paso el programa
desde el principio sera demasiado lento, as que la forma de depurar
estos errores es poner un punto de ruptura (breakpoint) en un punto
especfico del programa, ejecutar el programa todo seguido hasta
llegar al punto de ruptura y a continuacin ejecutar instruccin a
instruccin hasta encontrar el error. Cada vez que se alcance la
instruccin marcada con el punto de ruptura la ejecucin del
programa parar.
Para definir un punto de ruptura en tu programa pulsa con el botn
derecho sobre la instruccin donde quieres definirlo y selecciona Set

11

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Breakpoint. En ese momento la instruccin quedar marcada en el


panel Text con un icono de una mano indicando detencin. Cuando
quieras eliminar un punto de ruptura que hayas definido previamente
puedes hacerlo pulsando con el botn derecho y seleccionando Clear
Breakpoint.
Durante el proceso de depuracin puede interesarte poner los
registros a 0. Esto se hace con la opcin Clear Registers del men
Simulator, o directamente con el botn
de la barra de
herramientas. Cuando hagas esto, todos los registros pasarn a valer
0 excepto los registros Status y fp.
Tambin puede interesarte reinicializar el simulador. Puedes hacerlo
con la opcin Reinitialize del men Simulator o bien directamente
con el botn

Controlar
Display)

de la barra de herramientas.

lo

que

muestra

QtSpim

(Opciones

de

Las opciones que permiten controlar la forma en que QtSpim muestra


la informacin se encuentran en los mens Registers, Text
Segment y Data Segment. En ellos podrs encontrar diversas
opciones que permitirn mostrar o no algunos de los paneles de
instrucciones y datos. Por ejemplo, si no queremos que se muestren
las instrucciones que corresponden al ncleo del simulador, entonces
la opcin Kernel Text del men Text Segment deber estar
desactivada.
Adems, estos mens incluyen tambin opciones que permiten
seleccionar la forma en que se muestra la informacin dentro de
estos paneles, ya sea en binario, hexadecimal o decimal. Por ejemplo,
cuando la opcin Decimal dentro del men Registers est activada,
el contenido de los registros se mostrar en decimal.

Modificar el contenido de la memoria o de los


registros
En cualquier momento puedes cambiar el contenido de una posicin
de memoria o de un registro. Para ello debes pulsar con el botn
derecho del ratn sobre lo que quieres modificar y seleccionar la
opcin que desees (Change Register Contents o Change Memory
Contents), tal como se muestra en la Figura 2.

12

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Figura 2: Cambiando el contenido de un registro

Al hacerlo aparecer una nueva ventana, tal como muestra la Figura


3, pidiendo que introduzcas el nuevo valor que deseas almacenar en
el registro o en la posicin de memoria seleccionados, as como la
codificacin en la que est expresado dicho valor (hexadecimal o
decimal). Al pulsar OK vers cmo el valor almacenado cambia al
nuevo valor introducido.

Figura 3: Introduciendo el nuevo valor del registro

Opciones de simulacin de QtSpim


Es posible configurar el modelo que sigue QtSpim a la hora de
realizar la simulacin, as como ciertos parmetros de visualizacin

13

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

del programa. Estas opciones se encuentran en la opcin Settings


del men Simulator. Al seleccionar esta opcin aparece una ventana
como la mostrada en la Figura 4. Esta ventana tiene dos pestaas. La
que se muestra en la Figura 4 contiene las opciones que permiten
configurar el tipo de letra y los colores con los que se muestran tanto
las ventanas de registros como las del cdigo y los datos. Adems,
permite tambin personalizar el nmero de archivos recientes que
deben memorizarse en QtSpim.

Figura 4: Configuracin de parmetros de QtSpim

La otra pestaa se muestra en la Figura 5. En ella se configuran las


opciones de simulacin del modelo de procesador MIPS que
implementa QtSpim. Esto determinar la forma de funcionamiento del
simulador. Estas opciones son las siguientes:

Bare Machine. Hace que QtSpim simule un procesador MIPS


muy bsico. No permite el uso de pseudoinstrucciones dentro
de los programas, ni otras facilidades de programacin.
Enable Delayed Branches. Permite que el QtSpim
implemente la tcnica de salto retardado que consiste en que
cuando se encuentra una instruccin de salto el procesador
debe ejecutar la instruccin que est despus del salto antes de
hacer el salto efectivo, y calcular la nueva direccin del PC a
partir de la instruccin posterior al salto.

14

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Enable Mapped IO. Activa la entrada/salida mapeada en


memoria.
Accept Pseudo Instructions. Permite que los programas a
simular incluyan pseudoinstrucciones que el procesador MIPS
realmente no ejecuta. Durante la carga de los programas estas
pseudoinstrucciones sern sustituidas por el conjunto de
instrucciones MIPS equivalentes que hacen la misma funcin.
Enable Delayed Loads. Activar esta opcin hace que QtSpim
retrase el valor cargado de memoria a una instruccin posterior
a la instruccin de load.

Figura 5: Configuracin de opciones de simulacin

Existen adems dos botones de configuracin rpida, Simple


Machine y Bare Machine. Con el botn Simple Machine se
configura QtSpim como una mquina MIPS que permite
pseudoinstrucciones, que es la configuracin ms comnmente
utilizada, y la que usaremos a lo largo de todas las prcticas.
El botn Bare Machine configura el QtSpim para simular un
procesador MIPS real, es decir, con las opciones Bare Machine,
Delayed Branches y Delayed Loads activadas.
Por ltimo, la opcin Load Exception Handler indica si se debe
cargar un archivo que contiene el cdigo para realizar el manejo de
interrupciones.
Adems de todo lo comentado aqu QtSpim tambin proporciona
ayuda en lnea a travs del men Help, opcin View Help (o bien

15

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

directamente con el botn


de la barra de herramientas). Esta
ayuda muestra tanto el manual del QtSpim como un documento
sobre el lenguaje ensamblador, linkador y el simulador Spim.

Sintaxis del Lenguaje ensamblador del


MIPS R2000
A continuacin presentamos un resumen somero de la sintaxis del
lenguaje ensamblador del procesador MIPS R2000. Este resumen nos
permitir tener una visin general del lenguaje, en el que se ir
profundizando a medida que avancemos en la realizacin de las
prcticas de la asignatura.
Un programa escrito en lenguaje ensamblador est formado por un
conjunto de sentencias ordenadas una detrs de la otra. Cada una de
estas
sentencias
puede
contener
una
instruccin,
una
pseudoinstruccin o bien una directiva. Adems de lo anterior, cada
sentencia puede contener tambin un comentario, o una etiqueta.

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:

de carga o almacenamiento de datos


de movimiento de datos
aritmticas
lgicas
de comparacin
de control de flujo
de operaciones en coma flotante
de excepciones e interrupciones

Adems, dependiendo del tipo de operacin que realicen necesitarn


uno, dos o tres operandos. Los operandos especifican dnde estn los
datos necesarios para realizar la operacin y dnde debe guardarse el
resultado de la misma.
La sintaxis de las instrucciones incluye una palabra reservada que
indica la operacin a realizar y la especificacin de uno o ms
operandos.
Un ejemplo sera la instruccin siguiente:
add $8, $9, $10

que realiza la suma de los contenidos de los registros $9 y $10 y


almacena el resultado en el registro $8.

16

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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

que indica que la zona de memoria donde estn almacenados los


datos del programa comienza en la posicin de memoria 0x10010000 y
est compuesta por los datos que se relacionen a continuacin de la
directiva .data.

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

# suma el contenido de $9 y $10

17

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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

Donde dato1: es la etiqueta que hace referencia a la posicin de


memoria donde se encuentra el dato de tipo byte definido por la
directiva .byte.
En cuanto al valor 20 del ejemplo anterior, es preciso aclarar que los
nmeros se escriben, por defecto, en base 10. Si van precedidos de
0x, se interpretan en hexadecimal. Por otro lado, las cadenas de
caracteres se encierran entre comillas dobles () y los caracteres
especiales en las cadenas siguen la convencin del lenguaje de
programacin C:

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

# inicializo una posicin de


# memoria al valor 25

.text
.globl
main:

main

# debe ser global

lw $t0, dato($0)

2. Inicia el programa QtSpim, carga el programa que se muestra a


continuacin y ejecuta tres instrucciones del programa. A
continuacin responde a las siguientes cuestiones:

18

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

.data
dato1:

.word 15

dato2:

.word 20

# inicializo los datos del programa

.text
.globl

main

# las instrucciones de mi programa

main: add $8, $8, $10


lw $11, dato1($0)
sub $8, $11, $8
add $9, $8, $8

a. Qu valor tiene almacenado el registro Contador de


Programa (PC)?
b. Qu instruccin est almacenada en la posicin de
memoria 0x00400000?
c. Qu datos estn almacenados en la zona de datos de
usuario?
3. Reinicia la ejecucin del programa del ejercicio anterior y
ejecuta nueve instrucciones. A continuacin responde a las
siguientes cuestiones:
a. Busca tu programa en el panel del cdigo e indica en qu
direccin de memoria comienzan las instrucciones de tu
programa y en qu direccin terminan.
b. Qu instruccin est almacenada en la posicin de
memoria 0x00400034?
c. Qu valor est almacenado en este momento en el
registro $11, en decimal?
d. Si ejecutas una instruccin ms, qu valor est ahora
almacenado en el registro $11, en decimal? Ha variado?
Por qu? Por qu no?
e. Cul es el resultado final del programa?

19

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

20

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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:

Bytes: especifican datos de tamao 8 bits.


Media palabra (Half Word): especifican datos de tamao 16
bits (2 bytes).
Palabra (Word): especifican datos de tamao 32 bits (4
bytes). El tamao de la palabra coincide con el tamao del bus
de datos del procesador.
Doble palabra (Double): especifican datos de tamao 64
bits.
Cadenas de caracteres: especifican datos de tamao
variable. Cada elemento individual de la cadena es un carcter
ASCII de tamao 1 byte.

Adems de definir datos de los tipos anteriores, existe la posibilidad


de reservar zonas de memoria de un tamao definido e inicializarlas a
un valor determinado.
Todas estas posibilidades, y algunas ms, se estudiarn con detalle
en las secciones siguientes del captulo.

Definicin
programa

del

rea

de

datos

de

un

Para definir el comienzo del rea de datos de un programa se utiliza


la directiva .data. La forma genrica de la directiva es:
.data direccion

y su efecto es definir una zona de datos de usuario que comienza a


partir de la direccin especificada. Si no se especifica ninguna
direccin, entonces la direccin de comienzo sera la 0x10010000 de
memoria.

Cmo muestra QtSpim los datos en


memoria?
Al ejecutar QtSpim, antes de cargar cualquier programa la zona de
datos de usuario presenta el aspecto que se muestra en la Figura 6.

21

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

En esta figura podemos apreciar que la zona de datos de usuario


ocupa las direcciones de memoria 0x10000000 a la 0x10040000.
Adems, vemos que desde la direccin 0x10000000 a la 0x1003ffff el
contenido de la memoria est todo a 0.

Figura 6: Zona de datos de usuario al ejecutar QtSpim.

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

Byte en la direccin 0x7ffffa0c

Byte en la direccin 0x7ffffa08


Direccin de
comienzo

Byte en la direccin 0x7ffffa09


Byte en la direccin 0x7ffffa0a
Byte en la direccin 0x7ffffa0b

Figura 7: Ordenacin de los bytes en el panel de datos.

22

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

QtSpim ordena los datos cuando los muestra al usuario. Dentro de


cada fila QtSpim agrupa los datos en grupos de 4 bytes (1 palabra).
Adems, dentro de cada palabra, el byte que corresponde a la
posicin menos significativa se encuentra en la posicin ms a la
derecha. Observa en la Figura 7 que el byte menos significativo de la
primera palabra, cuya direccin es 0x7ffffa08 y con valor 04, est
colocado en la parte derecha de la palabra. A continuacin, yendo
hacia la izquierda, se colocan los siguientes bytes de la palabra. Por
lo tanto, el byte que corresponde a la posicin ms significativa de la
palabra se encuentra en la posicin ms a la izquierda. Esto lo puedes
observar tambin en la Figura 7, donde se muestra que el byte en la
direccin 0x7ffffa0b, con valor 00, se encuentra en la posicin ms a
la izquierda de la palabra.
Cuestiones
1. En la Figura 7, cul es el valor del byte ms significativo de la
palabra que comienza en la direccin 0x7ffffa0c?
2. En la Figura 7, en qu direccin de memoria comienza la
palabra cuyo valor es 0x7ffffac9?
3. Dada la Figura 8 que muestra los datos en memoria de un
programa de usuario cargado en el QtSpim,

Figura 8: Datos de un programa de usuario.

a. Cul es el valor de byte ms significativo de la palabra que


comienza en la direccin 0x10010000? Y en la
0x10010004?
b. Qu direccin tiene el byte con valor 27? Y el byte con
valor 19?
c. Cul es la direccin de la tercera palabra de datos a partir
de la direccin 0x10010000?
En general, cada byte de memoria tiene su propia direccin, y los
bytes de datos se almacenan de forma consecutiva en los bytes de
memoria. Ahora bien, a la hora de almacenar datos ms complejos
como las palabras, existen dos convenios: Little-Endian y Big-Endian.
La ordenacin de bytes tipo Little-Endian consiste en que los bytes
menos significativos de una palabra se colocan en las direcciones de
memoria ms bajas de la palabra. Por ejemplo, si almacenamos el

23

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

dato hexadecimal 0x12345678 a partir de la direccin de memoria


0x10010000 siguiendo la ordenacin Little-Endian, tendramos que
los datos se almacenara en memoria tal como muestra la Figura
9(a), en la que el byte menos significativo (0x78) estara en la
direccin ms baja (0x10010000) y los bytes siguientes en las
siguientes direcciones consecutivas (0x56 en la direccin
0x10010001, 0x34 en la direccin 0x10010002 y 0x12 en la direccin
0x10010003).
Por su parte, la ordenacin de bytes tipo Big-Endian consiste en que
los bytes ms significativos de una palabra se colocan en las
direcciones de memoria ms bajas de la palabra. Siguiendo con el
ejemplo anterior, la Figura 9(b) muestra cmo se almacenaran los
datos en memoria en este caso. El byte ms significativo 0x12 se
almacenara en la direccin ms baja de la palabra (0x10010000) y
los bytes siguientes en las siguientes direcciones consecutivas (0x34
en la direccin 0x10010001, 0x56 en la direccin 0x10010002 y 0x78
en la direccin 0x10010003).

0x78

0x10010000

0x12

0x56

0x10010001

0x34

0x34

0x10010002

0x56

0x12

0x10010003

(a)

0x78

(b)

Figura 9: Ordenacion de bytes (a) Little-Endian y (b) Big-Endian.

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

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Para definir palabras disponemos de la directiva .word que tiene la


sintaxis siguiente:
etiqueta: .word valor

En esta directiva etiqueta es el nombre simblico que se le


proporciona a la palabra definida y valor es el valor al que se inicializa
la palabra.
Ejercicio 1
En el directorio de trabajo crea un fichero con la extensin .s, por
ejemplo "ejercicio1.s", y con el siguiente contenido:
.data

# comienza zona de datos

palabra1:

.word 15

# decimal

palabra2:

.word 0x15

# hexadecimal

Este programa en ensamblador incluye una directiva .data que hace


que la zona de datos de usuario comience en la direccin
0x10010000. Ejecuta el programa QtSpim y carga el programa que
has creado con la opcin File/Load File.
Cuestiones
1. Encuentra los datos almacenados por el programa anterior en
memoria. Localiza dichos datos en el panel de datos e indica su
valor en hexadecimal.
2. En qu direcciones se han almacenado dichos datos? Por
qu?
3. Qu valores toman las etiquetas palabra1 y palabra2?
Ejercicio 2
Crea otro fichero o modifica el anterior con el siguiente cdigo:
.data 0x10010000 # comienza zona de datos
palabras:

.word 15,0x15

# decimal/hexadecimal

Borra los valores de la memoria con Simulator/Reinitialize


Simulator y carga el nuevo fichero.
Cuestiones
1. Comprueba si hay diferencias respecto al programa anterior.
2. Crea un fichero con un cdigo que defina un vector de cinco
palabras (word), que est asociado a la etiqueta vector, que
comience en la direccin 0x10000000 y con los valores 0x10,
30, 0x34, 0x20 y 60.
3. Comprueba que se almacena de forma correcta en memoria.
4. Qu ocurre si se quiere que el vector comience en la direccin
0x10000002? En qu direccin comienza realmente? Por qu?

25

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Definicin de bytes
Para definir bytes en memoria se utiliza la directiva .byte que tiene la
sintaxis siguiente:
etiqueta: .byte valor

Siendo valor el valor al cual se inicializa el byte definido, y etiqueta


el nombre simblico con el que nos podemos referir a ese byte
cuando necesitemos cargar o almacenar datos en l.
Ejercicio 3
Crea un fichero con el siguiente cdigo:
.data
octeto:

.byte

# comienza zona de datos


0x10

# hexadecimal

Borra los valores de la memoria con Simulator/Reinitialize


Simulator y carga el nuevo fichero.
Cuestiones
1. Qu direccin de memoria se ha inicializado con el contenido
especificado?
2. Qu valor se almacena en la palabra que contiene el byte?
3. Qu valor toma la etiqueta octeto?
Ejercicio 4
Crea otro fichero o modifica el anterior con el siguiente cdigo:
.data
palabra1:

.byte

0x10,0x20,0x30,0x40 # hexadecimal

palabra2:

.word

0x10203040

# hexadecimal

Borra los valores de la memoria con Simulator/Reinitialize


Simulator y carga el nuevo fichero.
Cuestiones
1. Cules son los valores almacenados en memoria?
2. Qu tipo de alineamiento y organizacin de los datos (Bigendian o Little-endian) utiliza el simulador? Por qu?
3. Qu valores toman las etiquetas palabra1 y palabra2?

Definicin de cadenas de caracteres


La directiva .ascii cadena permite cargar en posiciones de
memoria consecutivas, de tamao byte, el cdigo ASCII de cada uno
de los caracteres que componen cadena.

26

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Ejercicio 5
Crea un fichero con el siguiente cdigo:
.data
cadena:

.ascii "abcde"

octeto:

.byte 0xff

# defino una cadena

Borra los valores de la memoria y carga el nuevo fichero.


Cuestiones
1. Localiza la cadena anterior en memoria.
2. Qu ocurre si en vez de .ascii se emplea la directiva .asciiz?
Describe lo que hace esta ltima directiva.
3. Crea otro fichero que cargue la tira de caracteres cadena en
memoria de cuatro formas diferentes: utilizando la directiva
.ascii, utilizando la directiva .byte, utilizando la directiva .half
y utilizando la directiva .word.

Reservas de espacio en memoria


La directiva .space n sirve para reservar n bytes de espacio en
memoria para una variable, inicializndola a 0.
Ejercicio 6
Crea un fichero con el siguiente cdigo:
espacio:

.data

# comienza zona de datos

.space 1

# reservo espacio

.byte 0xff

Borra los valores de la memoria con Simulator/Reinitialize


Simulator y carga el nuevo fichero.
Cuestiones
1. Observa la disposicin de los datos en memoria. Vara el
nmero de bytes que se reservan en memoria a 2, 3, 4 y 5
bytes. En qu direccin de memoria se encuentra el byte con
valor 0xff en cada uno de los casos?
2. Sustituye en el programa original el valor 1 por un 8. Para ese
caso, qu rango de posiciones se han reservado en memoria
para la variable espacio? Cuntos bytes se han reservado en
total? Y cuntas palabras?

27

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Alineacin de datos en memoria


En ciertos casos es til forzar que los datos que se definen estn
alineados en una posicin de memoria determinada. Para ello se
dispone de la directiva .align, que tiene la sintaxis siguiente:
.align n

El efecto de esta directiva es alinear el siguiente dato a una direccin


mltiplo de 2n.
Ejercicio 7
Crea un fichero con el siguiente cdigo:
.data

# comienza zona de datos

byte1:

.byte

0x10

espacio:

.space

byte2:

.byte

0x20

palabra:

.word

10

Borra los valores de la memoria y carga el nuevo fichero.


Cuestiones
1. Qu rango de posiciones se han reservado en memoria para la
variable espacio? Estos cuatro bytes podran constituir los
bytes de una palabra? Por qu?
2. A partir de qu direccin se ha inicializado byte1? y byte2?
3. A partir de qu direccin se ha inicializado palabra? Por qu?
Ejercicio 8
Crea un fichero con el siguiente cdigo:
.data
byte1:

# comienza zona de datos

.byte 0x10
.align

espacio:

.space

byte2:

.byte

0x20

palabra:

.word

10

Borra los valores de la memoria y carga el nuevo fichero.


Cuestiones
1. Qu rango de posiciones se ha reservado en memoria para la
variable espacio? Estos cuatro bytes podran constituir los
bytes de una palabra? Por qu?
2. Qu ha hecho la directiva .align?

28

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

3. Cmo cambia la ubicacin de los datos en memoria si en lugar


de .align 2 ponemos .align 3?

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

a partir de la direccin 0x10010000 suponiendo que:


1. La matriz A se almacena por filas, de forma que los
elementos de una fila estn contiguos en memoria.
2. La matriz A se almacena por columnas, de forma que los
elementos de una columna estn contiguos en memoria.

29

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

6. Disea un programa en lenguaje ensamblador que reserve


espacio para guardar los datos personales de un usuario
siguiendo esta estructura: nombre (mximo 150 caracteres),
direccin (mximo 180 caracteres), edad (nmero entero),
telfonos (trabajo, casa y mvil), profesin (mximo 50
caracteres).
7. Disea la seccin de datos de un programa en lenguaje
ensamblador que genera nmeros aleatorios partir de un
nmero entero de entrada y tiene el siguiente comportamiento:
a. imprime por pantalla introduce un nmero entero,
b. el nmero es almacenado en memoria,
c. se hacen los clculos necesarios,
d. imprime por pantalla El nmero aleatorio generado es:,
e. imprime por pantalla el nmero generado.

30

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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

Load Upper Inmediate Instruccin

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

Definicin del rea del cdigo de un


programa
Para definir el comienzo del rea del cdigo de un programa se utiliza
la directiva .text. La forma genrica de la directiva es:
.text direccion

y su efecto es definir una zona de cdigo de usuario que comienza a


partir de la direccin especificada. Si no se especifica ninguna
direccin, entonces la direccin de comienzo del cdigo sera la

31

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

0x00400000 de memoria. La primera instruccin de nuestros


programas debe estar sealada por la etiqueta main: y sirve para
indicar al simulador cul es la primera instruccin a ejecutar de
nuestro cdigo. Esto no es una tarea trivial, ya que la primera
instruccin a ejecutar no tiene que ser necesariamente la primera
instruccin de la zona del cdigo. Por defecto la etiqueta main: hace
referencia a la direccin 0x00400024 de memoria.
A la hora de ejecutar nuestro programa QtSpim comienza la ejecucin
en la direccin 0x00400000. En esa posicin de memoria, y las
siguientes, existe un cdigo de inicializacin que el QtSpim siempre
incluye y ejecuta. Nuestros programas se consideran siempre
subrutinas de este programa original cargado en la direccin
0x00400000 y se salta a su ejecucin con la instruccin jal main,
que se encuentra cargada en la direccin 0x00400014. En la Figura
10 puede verse el cdigo de inicializacin que comienza en la
direccin 0x00400000 y se extiende hasta la direccin 0x00400014.

Figura 10: Cdigo de inicializacin y terminacin de ejecucin de un programa.

Adems, cuando nuestro programa termine su ejecucin debe hacer


un retorno al punto en que fue llamado (la instruccin siguiente a jal
main) incluyendo como ltima instruccin del programa la instruccin
jr $ra (o jr $31) y en ese momento se ejecutar un cdigo de
terminacin que se muestra tambin en la Figura 10, y que est
cargado en memoria desde la direccin 0x0040001c hasta la
direccin 0x00400020.

Carga de datos inmediatos


La carga de datos inmediatos se refiere a la forma de colocar
constantes en los registros, para luego utilizarlas en las instrucciones
posteriores.
Ejercicio 1
Crea un fichero con el siguiente cdigo:
.text
main:

# zona de instrucciones

lui $s0, 0x8690

32

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

La instruccin lui es la nica instruccin de carga inmediata real, y


almacena la media palabra que indica el dato inmediato de 16 bits en
la parte alta del registro especificado, en este caso s0. La parte baja
del registro se pone a 0.
Borra los valores de la memoria y carga el nuevo fichero.
Cuestiones
1. Localiza la instruccin en memoria de instrucciones e indica:
a. La direccin donde se encuentra.
b. El tamao que ocupa.
c. La instruccin mquina, analizando cada campo de sta e
indicando que tipo de formato tiene.
2. Ejecuta el programa con la opcin del men principal
Simulator/Run. Comprueba el efecto de la ejecucin del
programa en el registro.

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

Borra los valores de la memoria, carga el nuevo fichero y ejectalo


con la opcin del men principal Simulator/Run.
Cuestiones
1. Comprueba el efecto de la ejecucin del programa en el
registro.
2. Las pseudoinstrucciones no se corresponden con instrucciones
en lenguaje mquina que el procesador ejecute, as que la
pseudoinstruccin li debe ser traducida a instrucciones
directamente ejecutables. Comprueba qu conjunto de
instrucciones reales implementan la pseudoinstruccin li.

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

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

.data
palabra: .word 0x10203040
.text
main:

# zona de instrucciones

lw $s0, palabra($0)

La instruccin lw carga la palabra contenida en una posicin de


memoria, cuya direccin se especifica en la instruccin, en un
registro. Dicha posicin de memoria se obtiene sumando el contenido
del registro (en este caso $0, que siempre vale cero) y el identificador
"palabra".
Borra los valores de la memoria, carga el nuevo fichero y ejectalo
con la opcin del men principal Simulator/Run.
Cuestiones
1. Localiza la instruccin en memoria de instrucciones e indica
cmo ha transformado dicha instruccin el simulador.
2. Explica cmo se obtiene a partir de esas dos instrucciones la
direccin de palabra. Por qu crees que el simulador traduce
de esta forma la instruccin original?
3. Analiza cada uno de los campos que componen estas
instrucciones e indica el tipo de formato que tienen.
4. Comprueba el efecto de la ejecucin del programa.
5. Qu pseudoinstruccin permite cargar la direccin de un dato
en un registro? Modifica el programa original para que utilice
esta pseudoinstruccin, de forma que el programa haga la
misma tarea. Comprueba qu conjunto de instrucciones
sustituyen a la pseudoinstruccin utilizada una vez el programa
se carga en la memoria del simulador.
6. Modifica el cdigo para que en lugar de transferir la palabra
contenida en la direccin de memoria referenciada por la
etiqueta palabra, se intente transferir la palabra que est
contenida en la direccin referenciada por palabra+1. Explica
qu ocurre y por qu.
7. Modifica el programa anterior para que guarde en el registro
$s0 los dos bytes de mayor peso de "palabra". Nota: Utiliza la
instruccin lh que permite cargar medias palabras (16 bits)
desde memoria a un registro (en los 16 bits de menor peso del
mismo).

34

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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

siguiente: .byte 0x20


.text #
main:

zona de instrucciones

lb $s0, octeto($0)

La instruccin lb carga el byte de una direccin de memoria en un


registro. Al igual que en el caso de lw la direccin del dato se obtiene
sumando el contenido del registro $0 (en este caso siempre vale cero)
y el identificador "octeto".
Borra los valores de la memoria, carga el nuevo fichero y ejectalo
con la opcin del men principal Simulator/Run.
Cuestiones
1. Localiza la instruccin en memoria de instrucciones e indica
cmo ha transformado dicha instruccin el simulador.
2. Comprueba el efecto de la ejecucin del programa.
3. Cambia en el programa la instruccin lb por lbu. Qu sucede
al ejecutar el programa? Qu significa esto?
4. Si "octeto" se define como:
octeto:

.byte 0x30

existe diferencia entre el uso de la instruccin lb y lbu? Por


qu?
5. Indica cul es el valor del registro s0 si octeto se define
como:
octeto:

.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)

Por qu? Por qu en este caso no se produce un error de


ejecucin (excepcin de error de direccionamiento)?

35

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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)

La instruccin sw almacena la palabra contenida en un registro en una


direccin de memoria. Esta direccin se obtiene sumando el
contenido de un registro ms un desplazamiento especificado en la
instruccin (identificador).
Borra los valores de la memoria, carga el nuevo fichero y ejectalo
con la opcin del men principal Simulator/Run.
Cuestiones
1. Localiza la primera instruccin de tipo sw en la memoria de
instrucciones e indica cmo ha transformado dicha instruccin
el simulador.
2. Comprueba el efecto de la ejecucin del programa.

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

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

La instruccin sb almacena el byte de menor peso de un registro en


una direccin de memoria. La direccin se obtiene sumando el
desplazamiento indicado por el identificador y el contenido de un
registro.
Borra los valores de la memoria, carga el nuevo fichero y ejectalo
con la opcin del men principal Simulator/Run.
Cuestiones
1. Localiza la instruccin en memoria de instrucciones e indica
cmo ha transformado dicha instruccin el simulador.
2. Comprueba el efecto de la ejecucin del programa.
3. Modifica el programa para que el byte se almacene en la
direccin octeto+1. Comprueba y describe el resultado de
este cambio.
4. Modifica el programa anterior para transferir a la direccin de
octeto el byte en la posicin palabra+3.

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

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

programa deber reservar espacio en memoria para dos medias


palabras y una palabra y har lo necesario para que los bytes
0xab y 0xcd se organicen como media palabra (0xabcd), los
bytes 0xef y 0x10 se organicen como media palabra (0xef10) y
los bytes 0xab, 0xcd, 0xef y 0x10 se organicen como una
palabra (0xabcdef10) y se almacenen en las medias palabras y
la palabra reservadas.
7. Disea un programa en lenguaje ensamblador que defina en
memoria los caracteres a, d, n e y. Adems debe
reservar espacio, y construir, la cadena Adan nada y anda a
partir de los caracteres definidos.
8. Define los mnimos caracteres individuales necesarios para
construir la frase Raimundo era inmaduro, siguiendo la
filosofa del ejercicio anterior.

38

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

4. Interfaz del usuario con el


programa
Introduccin
Normalmente los programas necesitan de datos para realizar su
funcin, y en muchas ocasiones estos datos debe suministrarlos el
usuario. Adems, el resultado final de los programas debe poder
mostrarse tambin al usuario. Por lo tanto, es necesario que los
programas se comuniquen con los usuarios a travs de los
dispositivos especialmente pensados para ello, como el teclado, el
ratn o la pantalla. Realizar una comunicacin en lenguaje
ensamblador con uno de estos dispositivos no es una tarea sencilla.
Por ese motivo, el sistema operativo proporciona normalmente
servicios que permiten que esta comunicacin no la tenga que hacer
el programador directamente. En lugar de ello, son las rutinas del
sistema operativo las que incluyen el manejo a bajo nivel de los
dispositivos de entrada y salida de datos, y el programador de
lenguaje ensamblador puede invocar a estas rutinas de forma sencilla
para poder comunicarse con dichos dispositivos.

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

Leer una cadena

Resultado

Entero
$a0=direccin de la cadena
$a1= longitud de la cadena

Tabla 1: Servicios para interfaz del usuario con el programa

QtSpim posee una instruccin de llamada al sistema, denominada


syscall, que permite acceder a un conjunto de servicios del sistema
operativo. Estos servicios permiten introducir datos y visualizar
resultados de forma sencilla en los programas en lenguaje
ensamblador. Para solicitar un servicio, el programa debe cargar el
nmero que identifica el tipo de llamada al sistema en el registro $v0
y el/los parmetro/s en los registros $a0 a $a3. Las llamadas al
sistema que retornan valores ponen sus resultados en el registro $v0.

39

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

La interfaz del programa con el usuario se realizar a travs de una


ventana denominada Console que puede visualizarse u ocultarse
marcando la opcin Window/Console en el men principal del
QtSpim.
En la Tabla 1 se muestra un resumen de los servicios que
estudiaremos en este captulo. Para cada servicio se muestra el
nmero de identificacin o cdigo, los parmetros que son necesarios
y el resultado que devuelven (en caso de devolver alguno).

Impresin de una cadena de caracteres


En primer lugar estudiaremos cmo se realiza la impresin de una
cadena de caracteres en la pantalla. Este es el paso previo a poder
realizar la lectura de datos de entrada, ya que en primer lugar
debemos ser capaces de indicar al usuario que esperamos que se
introduzca alguna informacin, y qu tipo de informacin esperamos.
Ejercicio 1
.data
dir:

.asciiz "Hola. Ha funcionado."


.text

main:

li $v0,4

#cdigo de imprimir cadena

la $a0,dir

#direccin de la cadena

syscall

#llamada al sistema

Como ya estudiamos en el captulo anterior, la pseudoinstruccin li


carga de forma inmediata el dato que acompaa a la instruccin en el
registro especificado y la pseudoinstruccin la carga de forma
inmediata la direccin que acompaa la instruccin en el registro
especificado.
Borra los valores de la memoria, carga el fichero y ejectalo.
Cuestiones
1. Comprueba que se imprime la cadena de caracteres Hola. Ha
funcionado.. Vulvelo a ejecutar. Acurdate que antes de
volver a ejecutar el programa debes borrar el contenido de los
registros. Dnde se imprime el mensaje?
2. Introduce al final de la cadena los caracteres \n. Ejectalo dos
veces y comprueba cul es la diferencia con respecto al cdigo
original.
3. Modifica la lnea de la instruccin la ... para que slo se
imprima Ha funcionado..

40

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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:

.asciiz "Se va a imprimir el entero: "

entero:

.word

.text
main:

li $v0,4

#cdigo de imprimir cadena

la $a0,dir

#direccin de la cadena

syscall

#llamada al sistema

li $v0,1

#cdigo de imprimir entero

li $a0,5

#entero a imprimir

syscall

#llamada al sistema

Borra los valores de la memoria, carga el fichero y ejectalo.


Cuestiones
1. Comprueba la impresin del entero 5.
2. Modifica el programa para que se imprima el entero
almacenado en la direccin entero. Comprueba su ejecucin.

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:

.asciiz "Introduce el entero: "


.align 2

entero:

.space 4
.text

main:

li $v0,4 #cdigo de imprimir cadena


la $a0,dir

#direccin de la cadena

41

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

syscall

#llamada al sistema

li $v0,5 #cdigo de leer entero


syscall

#llamada al sistema

Borra los valores de la memoria, carga el fichero y ejectalo.


Introduce a travs del teclado un nmero entero de tu eleccin.
Cuestiones
1. Comprueba el almacenamiento del entero que has introducido
en el registro $v0.
2. Modifica el programa para que el entero ledo se almacene en la
direccin de memoria "entero".
3. Elimina la lnea .align 2 del programa anterior y ejectalo.
Qu ocurre? Por qu?

Lectura de cadena de caracteres


Ejercicio 4
Crea un fichero con el siguiente cdigo:
.data
dir:

.asciiz "Introduce la cadena de caracteres: "

buffer:

.space

10

.text
main:

li $v0,4 #cdigo de imprimir cadena


la $a0,dir

#direccin de la cadena

syscall

#llamada al sistema

li $v0,8 #cdigo de leer el string


la $a0,buffer

#direccin de lectura de cadena

li $a1,10

#espacio mximo de la cadena

syscall

#llamada al sistema

Borra los valores de la memoria, carga el fichero y ejectalo.


Introduce a travs del teclado la cadena de caracteres que t elijas.
Cuestiones
1. Comprueba el almacenamiento de la cadena de caracteres que
has introducido en buffer.
2. Qu ocurre si la cadena de caracteres que se escribe es ms
larga que el tamao reservado en buffer?

42

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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

A continuacin se deber imprimir los datos introducidos para


comprobar el correcto funcionamiento del programa.
3. Escribe un programa que lea del teclado dos nmeros enteros e
imprima la resta de los dos nmeros. Utiliza la instruccin sub
$rd, $rs, $rt que resta el contenido de los registros $rs y $rt,
dejando el resultado en el registro $rd.
4. Escribe un programa que lea del teclado el nombre (X) y la
edad (Y) del usuario y los almacene en memoria. El programa
deber escribir en la pantalla lo siguiente: Hola, te llamas X y
tienes Y aos., siendo X e Y los datos previamente introducidos
por el usuario.
5. Escribe un programa en lenguaje ensamblador que lea del
teclado un nmero entero (X) e imprima El doble del nmero
introducido X es Y. Utiliza la instruccin add $rd, $rs, $rt que
suma el contenido de los registros $rs y $rt, dejando el
resultado en el registro $rd.
6. Escribe un programa en lenguaje ensamblador que lea del
teclado un nmero entero e imprima el cudruple del nmero
introducido. Utiliza el menor nmero posible de instrucciones
add $rd, $rs, $rt que suman el contenido de los registros $rs
y $rt, dejando el resultado en el registro $rd.
7. Escribe un programa en lenguaje ensamblador que lea del
teclado una cadena de 10 caracteres e imprima por pantalla
otra cadena que se obtiene de sumar a cada carcter el valor

43

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

0x20. Si introduces tu nombre en minsculas, qu cadena se


obtiene como salida?

44

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

5. Las operaciones aritmticas


y lgicas
Introduccin
En este apartado se presentan las instrucciones que permiten realizar
operaciones aritmticas, lgicas y de desplazamiento. Entre las
primeras se encuentran las instrucciones de suma y resta (add, addu,
addi, addiu, sub, subu) y las instrucciones de multiplicacin y divisin
(mult, multu, div, divu). Las instrucciones acabadas en u consideran
los operandos como nmeros en binario puro, mientras que las
instrucciones no acabadas en u consideran los operandos de las
instrucciones como nmeros en complemento a dos. En ambos casos,
se producir una excepcin aritmtica si el resultado de la operacin
no es representable en 32 bits. Recuerda que el rango de
representacin de los nmeros enteros con signo de 32 bits en
complemento a 2 va desde 2.147.483.648 a 2.147.483.647
(0x80000000 a 0x7fffffff).
Dentro del grupo de instrucciones que permiten realizar operaciones
lgicas estn: suma lgica (or y ori), producto lgico (and y andi) y
la or exclusiva (xor y xori).
Finalmente, se presentan las instrucciones
aritmtico y lgico (sra, sll y srl).

de

desplazamiento

Operaciones
aritmticas
inmediatos (constantes)

con

datos

La instruccin addiu es una instruccin que suma el contenido de un


registro con un dato inmediato y sin deteccin de desbordamiento.
Ejercicio 1
.data
numero:

.word 2147483647
.text

main:

lw

$t0,numero($0)

addiu $t1,$t0,1

Borra los valores de la memoria, carga el fichero y ejectalo paso a


paso.

45

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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?

Operaciones aritmticas con datos en


memoria
En el comn de los casos los datos estn almacenados en memoria,
por lo que es necesario cargarlos previamente en registros para luego
hacer las operaciones necesarias con ellos.
Ejercicio 2
.data
numero1:

.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)

Borra los valores de la memoria, carga el fichero y ejectalo paso a


paso.
Cuestiones
1. Qu hace el programa anterior? Qu resultado se almacena

en numero3? Es correcto?
2. Se producir algn cambio si las instrucciones subu son
sustituidas por instrucciones sub? Por qu?

46

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Multiplicacin y divisin con datos en


memoria
Otra de las operaciones comunes a realizar con datos son las
multiplicaciones. En estos casos hay que tener en cuenta que la
multiplicacin de dos nmeros de N bits puede llegar a tener 2*N
bits. Dado que los datos a multiplicar pueden ser de 32 bits, esto
supone que el resultado puede ser de 64 bits. Por ese motivo hay que
utilizar dos registros especiales del procesador, HI y LO, ya que no
disponemos de registros de aritmtica entera de 64 bits. Adems, es
preciso utilizar instrucciones especficas que muevan los datos desde
los registros especiales HI y LO a los registros de propsito general
del procesador.
Ejercicio 3
Crea un fichero con el siguiente cdigo:
.data
numero1:

.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)

La instruccin mult multiplica dos registros de propsito general (en


el ejemplo anterior los registros $t0 y $t1) y deja el resultado de 64
bits en dos registros especiales de 32 bits llamados HI y LO (la parte
ms significativa del resultado en HI y la menos significativa en LO).
Las instrucciones mfhi y mflo sirven para mover los contenidos de
estos registros especiales a los registros de propsito general (en
este caso otra vez los registros $t0 y $t1). El cdigo realiza la
multiplicacin de dos nmeros, almacenando el resultado de la
multiplicacin a continuacin de los dos multiplicandos.
Borra los valores de la memoria, carga el fichero y ejectalo.

47

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Cuestiones
1. Qu resultado se obtiene despus de realizar la operacin?

Por qu se almacena en dos palabras de memoria? Cul es el


valor del registro HI? Por qu?
2. Modifica los datos anteriores para que numero1 y numero2

sean 10 y 3 respectivamente. Escribe el cdigo que divida


numero1 entre numero2 (dividendo y divisor respectivamente)
y coloque el cociente y el resto a continuacin de dichos
nmeros. Utiliza la instruccin div $rs, $rt que divide el
contenido de $rs entre el contenido de $rt y almacena el
cociente de la divisin en el registro LO y el resto en el registro
HI.

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)

El cdigo anterior pone a 0 los 16 bits ms significativos y el bit 0 de


nmero, almacenando el resultado en la siguiente palabra. Esto se
consigue utilizando la instruccin andi, que realiza el producto lgico
bit a bit entre el dato contenido en un registro y un dato inmediato. El
resultado que se obtiene es: aquellos bits que en el dato inmediato
estn a 1 no se modifican con respecto al contenido original del
registro, es decir, los 16 bits de menor peso excepto el bit 0. Por otro
lado, todos aquellos bits que en el dato inmediato estn a 0, en el
resultado tambin estn a 0, es decir, los 16 bits de mayor peso y el
bit 0. Los 16 bits da mayor peso se ponen a 0 puesto que, aunque el
dato inmediato que se almacena en la instruccin es de 16 bits, a la
hora de realizar la operacin el procesador trabaja con un dato de 32

48

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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

16 bits ms significativos de nmero permanezcan tal cual, y


que los 16 bits menos significativos queden a 0, excepto el bit 0
que tambin debe quedar como estaba. La solucin debe ser
vlida independientemente del valor almacenado en numero.
2. Modifica el cdigo para obtener, en la siguiente palabra, que los
16 bits ms significativos de nmero permanezcan tal cual, y
que los 16 bits menos significativos queden a 1, excepto el bit 0
que tambin debe quedar como estaba. La solucin debe ser
vlida independientemente del valor almacenado en numero.

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

El cdigo desplaza el nmero cuatro bits a la derecha, rellenando con


el bit del signo.

49

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Borra los valores de la memoria, carga el fichero y ejectalo.


Cuestiones
1. Para qu se ha rellenado el nmero con el bit del signo?
2. Qu ocurre si se sustituye la instruccin sra por srl?
3. Modifica el cdigo para desplazar el nmero tres bits a la

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

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

7. Multiplica el nmero 0x1237, almacenado en memoria a partir


de la direccin 0x10000000, por 32 (25) sin utilizar las
instrucciones de multiplicacin ni las pseudoinstrucciones de
multiplicacin.
8. Escribe un programa en lenguaje ensamblador que pida un
nmero de entrada y el nmero de veces que se desea rotarlo.
A continuacin debe realizar la rotacin del nmero a la
derecha tantas veces como se haya indicado. Nota: se debe
utilizar la instruccin ror $rd, $rs, $rt que rota a la derecha
el valor que est en el registro $rs el nmero de veces
especificado en el registro $rt y deja el resultado en el registro
$rd.

51

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

52

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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.

Instrucciones de salto condicional


El ensamblador del MIPS incluye dos instrucciones bsicas de ruptura
de secuencia condicional beq (branch if equal, saltar si igual) y bne
(branch if not equal, saltar si distinto). La sintaxis de estas
instrucciones es la siguiente:
beq $rs, $rt, etiqueta
bne $rs, $rt, etiqueta

Ambas comparan el contenido de los registros rs y rt y saltan a la


direccin de la instruccin referenciada por etiqueta si el contenido
del registro rs es igual al del rt (beq) o distinto (bne).
Adems se dispone de instrucciones de salto condicional para realizar
comparaciones con cero. Estas instrucciones son: bgez (branch if
greater or equal to zero, saltar si mayor o igual a cero), bgtz (branch
if greater than zero, saltar si mayor que cero), blez (branch if less or
equal to zero, saltar si menor o igual que cero), bltz (branch if less
than zero, saltar si menor que cero), y tienen la siguiente sintaxis:
bgez $rs, etiqueta
bgtz $rs, etiqueta
blez $rs, etiqueta

53

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

bltz $rs, etiqueta

Todas ellas comparan el contenido del registro rs con 0 y saltan a la


direccin de la instruccin referenciada por etiqueta si rs>=0 (bgez),
rs>0 (bgtz), rs<=0 (blez) rs<0 (bltz).

Instrucciones de salto incondicional


La instruccin de salto incondicional j permite romper la secuencia de
ejecucin del programa de forma incondicional y desviarla hacia la
instruccin referenciada mediante la etiqueta. Esta instruccin
presenta la siguiente sintaxis:
j etiqueta

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

A partir de este conjunto de instrucciones se puede implementar


cualquier estructura de control de flujo del programa.

Pseudoinstrucciones de salto condicional


Para facilitar la programacin, el lenguaje ensamblador del MIPS
aporta un conjunto de pseudoinstrucciones de salto condicional que
permiten comparar dos valores almacenados en registros (a nivel de
mayor, mayor o igual, menor, menor o igual) y segn el resultado de
esa comparacin saltan o no a la instruccin referenciada a travs de
la etiqueta. Estas pseudoinstrucciones son: bge (branch if greater or
equal, saltar si mayor o igual), bgt (branch if greater than, saltar si
mayor que), ble (branch if less or equal, saltar si menor o igual), blt
(branch if less than, saltar si menor que). La sintaxis es la misma
para todas ellas, solo sustituyendo xx por la condicin adecuada:
bxx $rs, $rt, etiqueta

El salto a la instruccin referenciada por etiqueta se efecta si el


resultado de la comparacin entre las variables contenidas en $rs y
$rt es: mayor o igual (ge), mayor (gt), menor o igual (le), o menor
(lt). La implementacin de estas pseudoinstrucciones se realiza a

54

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

partir de la instruccin slt y de las instrucciones de salto condicional


bsicas, beq y bne, principalmente.
Una
vez
introducidos
el
conjunto
de
instrucciones
y
pseudoinstrucciones que permiten implementar cualquier estructura
de control de flujo de programa, la siguiente seccin describe cmo
se implementan las estructuras ms tpicas de un lenguaje de alto
nivel. Estas son: Si-entonces, Si-entonces-sino, Mientras y Para
si se habla en lenguaje algortmico, o las estructuras if-then, ifthen-else, while, y for del lenguaje Pascal. De ellas, las dos
primeras son estructuras de control de flujo condicionales, y el resto
son estructuras de control de flujo repetitivas. Estas estructuras
dependen, implcita o explcitamente, de la verificacin de una o
varias condiciones para determinar el camino que seguir la ejecucin
del cdigo en curso. La evaluacin de esta condicin (o condiciones)
vendr asociada a una o varias instrucciones de salto condicional e
incondicional o pseudoinstrucciones.

Estructura de control condicional


entonces con condicin simple

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

and $t2, $t2,$0

#pone a 0 t2

add $t3, $t0,$t1

#t3 = t0+t1

Si:

beq $t1, $0, finsi

#si t1 = 0 finsi

entonces:

div $t0, $t1

#t0/t1

mflo $t2

#almacenar LO en t2

add $t2, $t3, $t2

#t2= t3 + t2

sw

#almacenar en memoria t2

finsi:

$t2, res($0)

55

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Borra los valores de la memoria, carga el fichero en el simulador y


ejectalo.
Cuestiones
1. Identifica la instruccin que determina la condicin y controla el
flujo de programa. Qu condicin se evala?
2. Identifica el conjunto de instrucciones que implementan la
estructura condicional si-entonces.
3. Qu valor se almacena en la variable res despus de
ejecutar el programa?
4. Si dato2=0, Qu valor se almacena en la variable res
despus de ejecutar el programa? Qu hace entonces el
programa?
5. Modifica el cdigo anterior para que la instruccin add $t3,
$t0, $t1 se realice despus de la estructura de control Sientonces en lugar de antes, sin modificar el resultado de la
ejecucin del programa.

Estructura de control condicional


entonces con condicin compuesta

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

and $t2, $t2,$0

#pone a 0 t2

add $t3, $t0, $t1

#t3=t0 + t1

beq $t1, $0, finsi

#si t1=0 saltar a finsi

beq $t0, $0, finsi

#si t0 =0 saltar a finsi

div $t0, $t1

#t0/t1

mflo $t2

#almacenar LO en t2

add $t2, $t3, $t2

#t2=t2 + t3

56

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

sw

$t2, res($0)

#almacenar en memoria t2

Borra los valores de la memoria, carga el fichero en el simulador y


ejectalo.
Cuestiones
1. Qu condicin compuesta se evala?
2. Modifica el cdigo anterior para que la condicin evaluada sea
((t1 > 0) y (t0 <> t1)). Comprueba el correcto funcionamiento
ante los siguientes valores:

dato1=40, dato2=30
dato1=0, dato2=40
dato1=40, dato2=-40

Estructura de control condicional


entonces-sino con condicin simple

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:

Borra los valores de la memoria, carga el fichero en el simulador y


ejectalo.

57

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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.

Estructura de control condicional Sientonces-sino con condicin compuesta


Ejercicio 4
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

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

$t3, $t1, entonces #si t3<t1 saltar a entonces

ble

$t3, $t2, sino

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

Borra los valores de la memoria, carga el fichero en el simulador y


ejectalo.
Cuestiones
1. Identifica qu condicin compuesta se evala.

58

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

2. Qu valor se almacena en res despus de ejecutar el


programa? Si dato1=40 y dato2=30, qu valor se almacena
en res despus de ejecutar el programa? Qu hace entonces
el programa?
3. Modifica el cdigo anterior para que la condicin evaluada sea
((dato3>=dato1) y (dato3<=dato2)).

Estructura de control repetitiva para


Ejercicio 5
Crea un fichero con el siguiente fragmento de cdigo que implementa
una estructura de control repetitiva Para:
.data
vector:

.word

6,7,8,9,10,-1

res:

.space

.text
main:

para:

la

$t2, vector

#t2 = vector

and

$t3, $0, $t3

#pone a 0 t3

li

$t0, 1

#carga 1 en t1

li

$t1, 6

bgt

$t0, $t1, finpara

# si t1=0 saltar a finpara

lw

$t4, 0($t2)

# carga un elemento en t4

add

$t3, $t4, $t3

#acumula la suma de los


#elementos del vector

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

Borra los valores de la memoria, carga el fichero en el simulador y


ejectalo.
Cuestiones
1. Qu hace la instruccin la $t2, vector?
2. Identifica en el fragmento de cdigo anterior qu conjunto de
instrucciones constituyen el bucle repetitivo y cuntas veces se
va a repetir.
3. Dentro del bucle se incrementa el contenido del registro $t2 en
cuatro unidades cada iteracin, por qu?

59

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

4. Dentro del bucle se decrementa el contenido del registro $t1 en


una unidad en cada iteracin, por qu?
5. Qu valor se almacena en res despus de ejecutar el cdigo
anterior? Qu hace entonces el programa?

Estructura de control repetitiva mientras


Ejercicio 6
Crea un fichero con el siguiente fragmento de cdigo que implementa
una estructura de control repetitiva Mientras:
.data
cadena:

n:

.asciiz

"hola"

.align

.space

.text
main:

la

$t0, cadena

#cargar la direccion de
#cadena en t0

mientras:

andi $t2, $t2, 0

#poner a 0 t2

lb

$t1, 0($t0)

#almacena un byte en t1

beq

$t1,$0,finmientras #si t1=0 saltar a finmientras

addi $t2, $t2, 1

#sumar 1 a t2

addi $t0, $t0,1

#sumar 1 a t0

j mientras

#saltar a mientras

finmientras: sw $t2, n($0)

#almacenar t2 en n

Borra los valores de la memoria, carga el fichero en el simulador y


ejectalo.
Cuestiones
1. Identifica en el fragmento de cdigo anterior qu conjunto de
instrucciones constituyen el bucle repetitivo y cuntas veces se
va a repetir.
2. Dentro del bucle se incrementa el contenido del registro $t0 en
una unidad por iteracin, por qu?
3. Qu valor se almacena en n despus de ejecutar el
programa?

60

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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

2. Disea un programa en ensamblador que dado un vector de


enteros V, obtenga como resultado cuntos elementos son
iguales a cero. Este resultado se debe almacenar sobre la
variable total. El programa deber inicializar los elementos del
vector en memoria, as como una variable n que almacenar
el nmero de elementos que tiene el vector y reservar espacio
para la variable resultado. El cdigo es el siguiente:
Para i=0 hasta n-1 hacer
Si (V(i)=0) entonces
total = total+1
Finsi
Fin Para

3. Disea un programa en ensamblador que dado un vector de


enteros V obtenga cuntos elementos de este vector estn
dentro del rango determinado por dos variables rango1 y
rango2. El programa deber inicializar los elementos del
vector en memoria, una variable n que almacenar el nmero
de elementos que tiene ese vector y dos variables donde se
almacenarn los rangos. Tambin deber reservar espacio para
la variable resultado. El cdigo es el siguiente:
Para i=0 hasta n-1 hacer
Si (V(i)>=rango1) y (V(i)<=rango2) entonces
res = res+1
Finsi
Fin Para

4. Disea un programa en ensamblador que dado un vector de


caracteres V, contabilice cuntas veces se repite un

61

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

determinado carcter en el mismo. La cadena estar definida


en la zona de datos, as como el carcter a buscar, que estar
en una variable llamada c. El resultado de la bsqueda se
almacenar en una variable resultado llamada res. El cdigo
es el siguiente:
Mientras (V(i)<>0) hacer
Si (V(i)=c) entonces
res = res+1
Finsi
i=i+1
Fin Mientras

5. Escribe un programa en lenguaje ensamblador que haga la


suma de los nmeros que se van introduciendo por el teclado.
El programa debe parar de hacer sumas cuando se introduzca
un valor 0 por el teclado. En ese momento debe imprimir el
resultado de la suma y terminar el programa.
6. Escribe un programa en lenguaje ensamblador que lea tres
nmeros del teclado e imprima el menor de los tres nmeros.
7. Escribe un programa en lenguaje ensamblador que lea un
nmero entero positivo. Si el nmero introducido no es positivo
el programa debe mostrar el mensaje Nmero invlido y
terminar su ejecucin. En otro caso el nmero debe imprimir el
nombre de los dgitos que forman el nmero, separados por un
espacio. Por ejemplo, si el nmero introducido es el 368 el
programa debe imprimir Tres Seis Ocho.

62

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Transferir datos hacia la pila (push o apilar). Antes de aadir un


dato a la pila se tienen que restar 4 unidades al puntero de pila
y a continuacin realizar el almacenamiento.
Transferir datos desde la pila (pop o desapilar). Para eliminar
datos de la pila, en primer lugar se debe leer el dato de la cima
de la pila y despus se tienen que sumar 4 unidades al puntero
de pila.

El ensamblador del MIPS tiene reservado un registro, $sp, como


puntero de pila (stack pointer). Para realizar una buena gestin de la
pila ser necesario que este puntero sea actualizado correctamente
cada vez que se realiza una operacin sobre la misma.
El siguiente fragmento de cdigo muestra cmo se puede realizar el
apilado de los registros $t0 y $t1 en la pila:
Ejercicio 1
.text
main:

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

Edita el programa, reinicializa el simulador y carga el programa.


Cuestiones
1. Ejecuta el programa paso a paso y comprueba en qu
posiciones de memoria, pertenecientes al segmento de pila se
almacena el contenido de los registros $t0 y $t1.
2. Modifica el programa anterior para que en lugar de actualizar el
puntero de pila cada vez que se pretende apilar un registro en
la misma, se realice una sola vez al principio y despus se
apilen los registros en el mismo orden.
3. Aade el siguiente cdigo al programa original despus de la
ltima instruccin:
a. Modifica el contenido de los registros $t0 y $t1,
realizando algunas operaciones sobre ellos.
b. Recupera el contenido inicial de estos registros
desapilndolos de la pila, y actualiza el puntero de pila
correctamente (limpiar la pila).
Ejecuta el programa resultante y comprueba si finalmente $t0 y
$t1 contienen los datos iniciales que se haban cargado.

64

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Comprueba tambin que el contenido del registro $sp contiene


el mismo valor antes y despus de la ejecucin del programa.

Llamada y retorno de una subrutina


El juego de instrucciones del MIPS R2000 dispone de una instruccin
especfica para realizar la llamada a una subrutina, jal etiqueta. La
ejecucin de esta instruccin conlleva dos acciones:

Almacenar la direccin de memoria de la siguiente palabra a la


que contiene la instruccin jal en el registro $ra.
Llevar el control de flujo de programa a la direccin etiqueta.

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

Reinicializa el simulador, carga el programa y ejectalo paso a paso,


contestando a las siguientes cuestiones:

65

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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.

Llamadas anidadas de subrutinas


Cuando una subrutina llama a otra utilizando la instruccin jal se
modifica automticamente el contenido del registro $ra con la
direccin de retorno (direccin de memoria de la siguiente palabra a
la que contiene la instruccin que ha efectuado el salto). Esto hace
que se pierda cualquier contenido anterior que pudiera tener este
registro, que podra ser a su vez otra direccin de retorno suponiendo
que se llevan efectuadas varias llamadas anidadas. As pues, en cada
llamada a una subrutina se modifica el contenido del registro $ra, y
slo se mantiene en este registro la direccin de retorno asociada a la
ltima llamada, Qu ocurre entonces con todas las direcciones de
retorno que deberan guardarse en llamadas anidadas?
Una solucin a este problema es que antes de ejecutar una llamada
desde una subrutina a otra se salve el contenido del registro $ra en la
pila. Como la pila crece dinmicamente, las direcciones de retorno de
las distintas llamadas anidadas quedarn almacenadas a medida que
stas se van produciendo. La ltima direccin de retorno apilada
estar en el tope de la pila, y sta es justamente la primera que se
necesita recuperar. As pues, una pila es la estructura adecuada para
almacenar las direcciones de retorno en llamadas anidadas a
subrutinas.
Ejercicio 3
El siguiente cdigo implementa una llamada anidada a dos
subrutinas: main y subr. A la primera se le llamar desde el
fragmento de cdigo que tiene el simulador para lanzar la ejecucin
de un programa de usuario y a la subrutina subr se la llamar desde
main. La primera necesita apilar la direccin de retorno (contenido de
$ra) para que sea posible la vuelta a la instruccin siguiente desde
donde se hizo la llamada a la rutina main. La segunda como no hace
ninguna llamada a otra subrutina no necesita apilar el contenido de
$ra:
.data
suma:

.space

66

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

.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

#apilar direccin de retorno

#desapilar direccin de retorno

Reinicializa el simulador, carga el programa y ejectalo paso a paso


respondiendo a las siguientes cuestiones:
Cuestiones
1. Comprueba qu contiene el registro $ra y el PC antes y despus
de ejecutar la instruccin jal main.
2. Comprueba qu hay almacenado en el tope de la pila despus
de ejecutar las dos primeras instrucciones del programa.
3. Comprueba el contenido de los registros $ra y PC antes y
despus de ejecutar la instruccin jal subr.
4. Comprueba el contenido de los registros $ra y PC antes y
despus de ejecutar la instruccin jr $ra que est en la
subrutina subr.
5. Comprueba el contenido de los registros $ra y PC antes y
despus de ejecutar la instruccin jr $ra que est en la
subrutina main.
6. Qu hubiera ocurrido si antes de ejecutar la instruccin jr $ra
de esta subrutina main no se hubiese desapilado el contenido
del registro $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:

Pasarlos por valor: se pasa el valor del parmetro.


Pasarlos por referencia: se pasa la direccin de memoria donde
est almacenado el valor del parmetro.

67

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

En lo que se refiere a dnde se le pasan los parmetros, las opciones


son:

Pasarlos en registros
Pasarlos en la pila

El ensamblador del MIPS establece adems el siguiente CONVENIO


para realizar el paso de parmetros:

Los cuatro primeros parmetros de entrada se pasarn a travs


de los registros $a0-$a3. A partir del quinto parmetro se
pasarn a travs de la pila.
Los dos primeros parmetros de salida se devuelven a travs
de los registros $v0-$v1, el resto a travs de 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:

Las dos variables que determinan el rango, pasados por valor,


en los registros $a0 y $a1.
La variable que se tiene que estudiar si est dentro del rango,
pasada por valor, en el registro $a2.

Parmetros de salida:

Variable booleana que indica si la variable estudiada est o no


dentro del rango, pasada por valor y devuelto en el registro
$v0.
.data

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

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

lw

$ra,0($sp)

addi

$sp,$sp,4

#desapilar ra

jr

$ra

#terminar ejecucion programa

blt

$a2,$a0,sino

#Si $a2<$a0 saltar a sino

bgt

$a2,$a1,sino

#si $a2>$a1 saltar a sino

addi

$v0,$0,1

#v0=1

finsi

#saltar a finsi

sino:

add

$v0,$0,$0

#v0=0

finsi:

jr

$ra

#retornar

subr:

entonces:

Reiniciliza el simulador, carga el programa, ejectalo y comprueba el


resultado almacenado en la posicin de memoria res.
Cuestiones
1. Identifica las instrucciones que se necesitan en el programa que
hace la llamada para:
a. La carga de parmetros en los registros.
b. La llamada a la subrutina.
c. El almacenamiento del resultado.
2. Identifica las instrucciones que se necesitan en la subrutina
para:
a. La lectura y procesamiento de parmetros.
b. La carga del resultado en $v0.
c. El retorno al programa que ha hecho la llamada.

Bloque de activacin de una subrutina


El bloque de activacin de la subrutina es el segmento de pila que
contiene toda la informacin referente a una llamada a una subrutina
(parmetros pasados a travs de la pila, registros que modifica la
subrutina y variables locales). Un bloque tpico abarca la memoria
entre el puntero de bloque (normalmente llamado regisro $fp en el
ensamblador del MIPS, se trata del registro $30), que apunta a la
primera palabra almacenada en el bloque, y el puntero de pila ($sp),
que apunta a la ltima palabra del bloque. El puntero de pila puede
variar su contenido durante la ejecucin de la subrutina y, por lo
tanto, las referencias a una variable local o a un parmetro pasado a
travs de la pila podran tener diferentes desplazamientos relativos al
puntero de pila dependiendo de dnde estuviera ste en cada
momento. De forma alternativa, el puntero de bloque apunta a una
direccin fija dentro del bloque. As pues, la subrutina en ejecucin
usa el puntero de bloque de activacin para acceder mediante
desplazamientos relativos a ste a cualquier elemento almacenado en

69

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

el bloque de activacin independientemente de dnde se encuentre el


puntero de pila.
Los bloques de activacin se pueden construir de diferentes formas.
No obstante, lo que realmente importa es que el programa que hace
la llamada y la subrutina deben estar de acuerdo en la secuencia de
pasos a seguir. Los pasos que se enumeran a continuacin describen
la convencin de llamada y retorno de una subrutina que se siguen.
Esta convencin interviene en varios puntos durante una llamada y
retorno a una subrutina: en el programa que realiza la llamada,
inmediatamente antes de llamar a la subrutina e inmediatamente
despus del retorno de la misma, en el momento justo en el que la
subrutina empieza su ejecucin e inmediatamente antes de realizar el
retorno en la subrutina:

En el programa que hace la llamada:


o Inmediatamente antes de hacer la llamada a la subrutina:
Se deben cargar los parmetros de entrada (y los de
salida si se pasan por referencia) en los lugares
establecidos, los cuatro primeros en registros y el resto
en la pila.
o Inmediatamente despus del retorno de la subrutina: Se
debe limpiar la pila de los parmetros almacenados en
ella, actualizando el puntero de pila.
En la subrutina:
o En el momento que empieza la ejecucin:
Reservar espacio en la pila para apilar todos los
registros que la subrutina vaya a modificar y para
las variables locales que se almacenarn en la pila.
Puesto que el registro $fp es uno de los registros
modificados por la subrutina, va a ser utilizado
como puntero al bloque de activacin, deber
apilarse. Para que la posterior limpieza del bloque
de activacin sea ms sencilla, conviene apilarlo
como primera palabra detrs de los parmetros que
ha apilado el programa que ha hecho la llamada (si
los hubiese).
Actualizar el contenido del registro $fp, para que
apunte a la posicin de la pila donde acabamos de
almacenar el contenido del $fp.
Apilar el contenido del resto de registros que se van
a modificar, que pueden ser: $t0-$t9, $s0-$s7,
$a0-$a3, $ra.
o Inmediatamente antes del retorno:
Recuperar el contenido de los registros apilados y
actualizar el puntero de pila para limpiar la pila.

El bloque de activacin de una subrutina tendra, por lo tanto, la


siguiente estructura:

70

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

Parmetros 5,6.... Parmetros apilados por el


+
programa que hace la llamada
fp -->
Registro fp
Registro ra
Registros apilados por la
Registros a0-a3
subrutina
Registros s0-s7
Registros t0-t9
variables
locales
sp -->
Ejercicio 5
El siguiente programa implementa una subrutina que calcula los
elementos nulos de un vector. Los parmetros de entrada son:

La dimensin del vector (pasado por valor).


La direccin del primer elemento del vector (pasado por
referencia).

Estos parmetros se pasarn a travs de la pila ya que el objetivo


que se pretende remarcar con este programa es la gestin del bloque
de activacin de una subrutina. Segn el convenio establecido, estos
parmetros se pasaran a travs de los registros $a0 y $a1.
Los parmetros de salida son:

Contador de elementos nulos del vector. Este parmetro se


devolver a travs del registro $v0.

En la subrutina se termina de crear el bloque de activacin de la


subrutina, que estar formado por los parmetros que se han pasado
a travs de la pila (parmetros de entrada) y por los registros que
vaya a modificar la subrutina, que apilar al principio de la ejecucin
de la subrutina. No se reserva espacio para variables locales puesto
que se utilizan registros para almacenarlas.
Por otro lado, para que se pueda apreciar mejor la evolucin del
bloque de activacin de la subrutina en distintos puntos del
programa, en el programa main lo primero que se hace es inicializar
los registros $s0, $s1, $s2 y $fp a unos valores arbitrarios. Al finalizar
la ejecucin del programa el contenido de estos registros debera ser
el mismo que al comienzo.
.data
n1:

.word

vec1:

.word

1,0,0,2

nul1:

.space

.text
#en primer lugar se inicializan los registros s0, s1, s2 y fp

71

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

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

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

#bucle que cuenta elementos nulos

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

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

a. Situacin 1: Antes y despus de ejecutar la instruccin


addi $sp,$sp,-8.
b. Antes y despus de ejecutar la instruccin jal subr.
(situacin justo antes de llamar a la subrutina).
Subrutina:
c.
d.
e.
f.
g.
h.
i.
j.
k.
l.

Despus de ejecutar la instruccin addi $sp,$sp,-16.


Despus de ejecutar la instruccin sw $fp,12($sp).
Despus de ejecutar la instruccin addi $fp,$sp,12.
Despus de ejecutar la instruccin sw $s2,-12($fp).
Despus de ejecutar la instruccin lw $s0,4($fp).
Despus de ejecutar la instruccin lw $s1,4($fp).
Despus de ejecutar el bucle (denominado bucle).
Antes y despus de ejecutar addi $sp,$fp,0.
Despus de ejecutar lw $fp,0($sp).
Despus de ejecutar addi $sp,$sp,4. Comprobar qu la
situacin de la pila y de los registros $sp y $fp es la
misma que justo antes de llamar a la subrutina).
m. Despus de ejecutar jr $ra.

Programa que hace la llamada despus de retornar de la


subrutina:
n. Antes y despus de ejecutar addi $sp,$sp,8. Comprobar
qu el contenido de los registros y de la pila se
corresponde con la situacin 1.

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

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

3. Modifica el cdigo original del programa del ejercicio 4 de esta


prctica para que los parmetros que se pasan a la subrutina
subr, tanto los de entrada como el de salida, se pasen por
referencia. Los pasos a realizar tanto por el programa que hace
la llamada como por la subrutina son los siguientes:
En el programa que hace la llamada:
a. Cargar la direccin de los parmetros en los registros
correspondientes (entrada y salida).
b. Llamada a la subrutina.
En la subrutina:
c. Lectura de los parmetros de entrada a partir de las
direcciones pasada como parmetro.
d. Procesamiento de los parmetros de entrada y generacin
del resultado.
e. Almacenamiento del resultado en la direccin de memoria
pasada a travs del parmetro de salida
f. Retorno al programa que hizo la llamada.
Ejecuta el programa obtenido y comprueba que el resultado
obtenido es el mismo que el del programa original.
4. Modifica el cdigo del programa del ejercicio 4 de esta prctica
para que los parmetros de entrada a la subrutina se pasen por
valor mediante la pila y el de salida se pase tambin a travs
de la pila, pero por referencia. A continuacin se muestra un
esquema de cmo debe ser la situacin de la pila en el
momento que empieza a ejecutarse la subrutina:
rango1 +
rango 2
dato
sp -->
res
5. Modifica el cdigo del programa del ejercicio 5 de esta prctica
para que los parmetros se pasen a travs de los registros $a0$a1 y el de salida a travs de $v0. Supongamos que el
programa que hace la llamada pretende que despus de
ejecutar la subrutina estos registros contengan el mismo
contenido que el que se ha cargado inicialmente en el
programa.
6. Implementa una subrutina en ensamblador que calcule cuntos
elementos de un vector de enteros de dimensin N son iguales
a un elemento dado:
a. Parmetros de entrada a la subrutina: direccin del
primer elemento del vector, total de elementos del vector
(dimensin), elemento a comparar.
b. Parmetro de salida de la subrutina: contador calculado.
Realiza las siguientes implementaciones:

75

Introduccin a Informtica - Prcticas de Laboratorio de


Introduccin a los Computadores

a. Implementa la subrutina de forma que todos los


parmetros que se le pasan sean por valor excepto
aqullos que obligatoriamente se deban pasar por
referencia, y a travs de registros.
b. Implementa la subrutina de forma que todos los
parmetros se pasen por referencia y a travs de
registros.
c. Implementa la subrutina donde los parmetros que se
pasan sean del mismo tipo que en el primer caso pero
utilizando la pila como lugar para realizar el paso de
parmetros.
d. Implementa una subrutina en ensamblador, tal que dado
un vector de enteros de dimensin n obtenga el elemento
(i) de dicho vector. La subrutina tendr como parmetros
de entrada: la direccin del vector, la dimensin del
mismo y el del elemento a devolver. La subrutina
devolver el elemento i-simo. Realiza la llamada y el
retorno a la subrutina segn el convenio establecido.
7. Implementa una subrutina en ensamblador, tal que dada una
matriz de enteros de dimensin n x m, almacenada por filas,
obtenga el elemento (i,j) de dicha matriz. La subrutina tendr
como parmetros de entrada: la direccin de la matriz, las
dimensiones de la misma y los ndices elemento a devolver. La
subrutina devolver el elemento (i,j). Realiza la llamada y el
retorno a la subrutina segn el convenio establecido.

76

Potrebbero piacerti anche