Sesión 3

Programando en lenguaje ensamblador del MIPS R2000


3.1 Objetivo General

Introducir los conceptos fundamentales de la programación en lenguaje ensamblador del procesador MIPS R2000.

3.2 Objetivos específicos

Al terminar esta sesión de laboratorio:

3.3 Lenguaje ensamblador

Como habrás notado en los programas de las sesiones anteriores, cada línea puede concluir con un comentario. Los comentarios comienzan con el carácter "#", a partir del cual el ensamblador ignora los restantes caracteres en la linea.

3.3.1 Etiquetas

En un programa en lenguaje ensamblador, una etiqueta es simplemente un nombre para una localidad o dirección de memoria. En el MIPS cada dirección es un valor de 32bits, de manera que las etiquetas no son más que valores de 32bits cuando se las usa en programas de ensamblador.

3.4 La CPU y los coprocesadores del MIPS

La unidad entera del MIPS (la CPU) cuenta con 32 registros de propósito general que almacenan valores enteros de 32bits. Los nombres de los registros van desde $0 hasta $31, y tienen nombres alternativos según se muestra en la tabla siguiente.

Número
Simbólico
Función
$0 $zero siempre contiene cero
$1 $at utilizado por assembler, no lo uses
$2-$3 $v0, $v1 valores de retorno de subrutina
$4-$7 $a0-$a3 argumentos de subrutina
$8-$15 t0-$t7 registros temporarios
$16-$23 $s0-$s7 registros subrutina de subrutina, tienen que ser guardados
por una funcion llamada antes de que puedan ser usados
$24,$25 $t8, $t9 registros temporarios, pueden ser sobreescritos por registros reservados del manejador interrupt/trap desubrutina, no usar puntero global, usado para acceder a variables estaticas y externas
$26,$27, $28 $k0, $k1, $gp
$29 $sp stack pointer
$30 $s8/$fp registro de subrutina, utilizado comunmente como frame pointer
$31 $ra direccion de retorno

Además de por la CPU, los procesadores MIPS están formados por una colección de coprocesadores que realizan tareas auxiliares u operan sobre tipos de datos, como los números de punto flotante. En XSPIM se simulan dos coprocesadores. El coprocesador 0 maneja las excepciones, las interrupciones y el sistema de memoria virtual, aunque los detalles sobre este último se omiten. El coprocesador 1 conforma la unidad de procesamiento de números de punto flotante.

3.5 Instrucciones para suma y resta

El número natural de operandos para una operación como la suma es tres: los dos números que se suman y el lugar donde se recibe la suma. Con el propósito de lograr que el hardware se mantenga simple, en la arquitectura MIPS la mayoría de las instrucciones artiméticas y lógicas tienen exactamente tres operandos.

A diferencia de los programas en lenguaje de más alto nivel, los operandos de las instrucciones aritméticas en ensamblador del MIPS no pueden ser variables, sino solamente registros. Es tarea de los compiladores el asociar eficientemente las (posiblemente numerosas) variables de los programas con los (relativamente pocos) registros con que cuanta la arquitectura MIPS.

En la siguiente tabla se muestran las instrucciones del ensamblador del MIPS que sirven para sumar y restar.

Instrucción
Ejemplo
Significado
Comentarios
add add $1, $2, $3 $1=$2+$3 3 operandos; datos en registros
subtract sub $1, $2, $3 $1=$2-$3 3 operandos; datos en registros

3.6 Instrucciones de transferencia de datos

Como en MIPS las operaciones artiméticas sólo ocurren entre registros, el lenguaje ensamblador debe incluir instrucciones que transfieren datos entre la memoria y los registros. Para referirse a una palabra en memoria, una instrucción debe proveer su dirección. La memoria puede considerarse como un enorme arreglo unidimensional y las direcciones (empezando en cero) son simplemente los índices a este arreglo. Como no sólo las palabras, sino tambien los bytes son útilesen muchos programas, la arquitectura MIPS direcciona a los bytes individuales; cuando se dice "Memory[i]", se esta haciendo referencia al i-ésimo byte de la memoria, y no a la i-ésima palabra de la memoria.

La instrucción de transferencia que mueve datos de la memoria a los registros se llama load (carga) y su contraparte, que transfiere datos de los registros a la memoria, se llama store (almacena). El formato y significado de ambas instrucciones se presenta en la siguiente tabla.

Instrucción
Ejemplo
Significado
Comentarios
load word lw $1, 100($2) $1= Memory[$2 +100] Datos de la memoria a los registros
store word sw $1, 100($2) Memory[$2 + 100]=$1 Datos de los resgistros a la memoria

Como puede verse, el formato de de las instrucciones load y store es idéntico: el nombre de la instrucción seguido del registro a ser cargado (almacenado), la dirección inicial de memoria y, finalmente, un registro que contiene el desplazamiento, a partir de la dirección inicial, del elemento que será almacenado (cargado).


Ejemplo 3.1
Supongamos que A es un arreglo de palabras (números de 32bits) y que el compilador ha asociado las variables g y h con los registros $17 y $18, respectivamente. Supongamos también que en el registro $19 se encuentra almacenado el valor 4 x i y que A comienza a almacenarse en la dirección Astart. La expresión en java g= h + A[i] se traduce a ensamblador del MIPS como
        lw $8, Astart($19) #el registro $8 recibe temporalmente a A[i]
        add $17, $18, $8 #g=h + A[i]


3.7 La pseudoinstrucción move

La pseudoinstrucción move es usada simplemente para copiar el valor almacenado en un registro a otro resgistro, como se explica en la siguiente tabla.

Instrucción
Ejemplo
Significado
Comentarios
move move $1, $2 $1=$2 Copia de datos entre registros

3.8 Modos de direccionamiento

La MIPS es una arquitectura de carga/almacenamiento, lo que significa que sólo las instrucciones loda y store tienen acceso a la memoria. Las instrucciones que realizan cálculos operan sólo sobre valores en registros. La máquina MIPS llana (bare) sólo provee el tipo de direccionamiento de memoria c(rx) que vimos en las instrucciones lw y sw (ver la tabla anterior de load y store) y que usa la suma del valor inmediato (i.e. constante) c y el almacenado en el registro xx como la dirección. La máquina virtual MIPS, que es la usamos al programar en ensamblador, nos provee los modos de direccionamiento para instrucciones de carga y almacenamiento que se presenta en la siguiente tabla.

Formato
Cálculo de la dirección
(registro) contenido del registro
inm inmendiato
inm(registro) inmediato + contenido del registro
símbolo dirección del símbolo (definido por una etiqueta)
símbolo ± inm dirección del símbolo ± inmendiato
símbolo ± inm(registro) dirección del símbolo ± (inmendiato + contenido del registro)

Ejemplo 3.2
Supongamos que en el registro $t1 se encuentra el valor 0x10000000 y que el símbolo S se encuentra almacenado en la memoria a partir de la dirección 0x10000000. Las siguientes instrucciones son equivalentes:
   lw $t0, ($t1)
   lw $t0, 0x10000000
   lw $t0, 0($t1)
   lw $t0, S
   lw $t0, S + 0
   lw $t0, S - 0($0)


3.9 Preguntas y ejercicios de revisión

1. Supongamos que A es un arreglo de palabras y que el compilador ha asociado a la variable h con el registro $17. Supongamos también que en el registro $19 se encuentra almacenado el valor 4 x i y que A comienza a almacenarse en la dirección Astart. ¿Cuál es el código en ensamblador del MIPS que corresponde a la siguiente expresión en java? A[i] = h - A[i];

2. ¿Por qué en el ejercicio anterior y en el ejemplo 3.1 se considera el valor 4 x i y no simplemente el valor i?

3. Haz un programa en ensamblador (pqrs.s) que imprima como salida la linea (p + q) - (r + s) = 18
Usa las lineas de código
         .data
p:      .word 13 #p=13
q:      .word 20 #q=20
r :      .word 6 #r=6
s :      .word 9 #s=9
para comenzarlo.

4. Consulta la documentación de XSPIM y describe brevemente todas las variables de las instrucciones de suma, resta, carga, almacenamiento y movimiento de datos de tipo entero.

5. Supongamos que el ensamblador del MIPS no tuviera dada explicitamente una manera de copiar datos entre registros. Explica cómo podrías emular (con las otras instrucciones que conoces) esta operación.

Cuando en una sesión de laboratorio se requiera realizar un programa y/o reporte, éste deberá entregarse por e-mail. El mensaje electrónico deberá contener un archivo .tar.z o .tgz( o en su defecto .zip) con los programas incluidos y/o el reporte de la sesión (si es necesario). Al expandir el archivo tgz, deberá contener un directorio llamado como el login de tu cuenta, luego un subdirectorio llamado como la sesión (por ejemplo sesion1, o sesion2), finalmente, los programas y/o reportes a entregar. Los reportes deberán ser enviados en formato postscript (ps) o en archivo PDF, cualquier otro formato no será recibido. Y algo muy importante, los programas y/o reportes deberán de entregarse en la fecha indicada, no se recibirán después.

Volver a la Introducción