Documente Academic
Documente Profesional
Documente Cultură
NDICE
Introduccin. Estructura de los programas de ensamblador MIPS. Tipos de datos. Registros. Datos, carga y almacenamiento y direccionamientos. Operaciones aritmticas bsicas. Operaciones de salto. Entrada y salida. Llamadas al sistema. Subprogramas. Instrucciones en punto flotante. Codificacin de las instrucciones.
2
INTRODUCCIN
El lenguaje ensamblador difiere de los lenguajes de alto nivel en que son dependientes, y por lo tanto ms cercanos a la arquitectura de la mquina. El estudio de un lenguaje de ensamblador permite conocer la arquitectura y el funcionamiento de los ordenadores. Hemos elegido MIPS por ser un lenguaje ensamblador sencillo, con un reducido conjunto de instrucciones. MIPS (siglas de Microprocessor without Interlocked Pipeline Stages) es toda una familia de microprocesadores de arquitectura RISC (Reduced Instruction Set Computer) desarrollados por MIPS Technologies. Los diseos del MIPS son utilizados en la lnea de productos informticos de SGI; en muchos sistemas embebidos; en dispositivos para Windows CE; routers Cisco; y videoconsolas como la Nintendo 64 o las Sony PlayStation, PlayStation 2 y PlayStation Portable. Para poder realizar las prcticas de ensamblador MIPS en una mquina con una familia de procesadores diferentes, vamos a usar un simulador. PCSpim
3
ESTRUCTURA DE UN PROGRAMA
Un programa en ensamblador ser un fichero de texto plano, que usar el sufijo .s Los programas debern estar comentados. Se considera un comentario todo lo que sigue a #
# esto es un ejemplo de comentario
Los programas empiezan por la seccin de declaracin de datos, seguido por la seccin de cdigo. La seccin de datos se identifica por la directiva .data En la seccin de datos se declaran los nombres de variables que se usan en el programa (se almacenarn en la memoria principal) La seccin de cdigo se identifica por la directiva .text Contiene las instrucciones del programa y el punto de comienzo del mismo se identifica por la etiqueta main: El punto de finalizacin del main suele ser una llamada al sistema exit (se carga el cdigo 10 en $v0 y se invoca a syscall)
TIPOS DE DATOS
Todas las instrucciones son de 32 bits 1 byte = 8 bits 1 halfword = 2 bytes 1 word = 4 bytes Un carcter requiere un byte de almacenamiento Un entero requiere un word de almacenamientos Las constantes numricas se expresan con el nmero. Por ejemplo 4 Las constantes de caracteres se expresan entre comillas simples. Por ejemplo a b Las cadenas de caracteres (strings) entre comillas dobles esto es una cadena de caracteres
7
LOS REGISTROS
Existen 32 registros de propsito general Para nombrarlos se pone el smbolo $ Existe dos formas diferentes de llamar a los registros:
Usando exclusivamente $ y su nmero, por ejemplo $0 a $31 Usando su nombre equivalente, por ejemplo $t1, $sp
Existen dos registros especiales $lo y $hi que se usan para almacenar resultados de la multiplicacin y la divisin. No se puede acceder directamente a ellos como los anteriores, sino que hay que hacerlo a travs de instrucciones especiales mfhi (move from hi), o mflo (move from lo) La pila crece siempre desde memoria alta hacia memoria baja ($sp es el puntero de pila stack pointer)
DECLARACION DE DATOS
Recuerda: La seccin de datos se identifica por la directiva .data .En la seccin de datos se declaran los nombres de variables que se usan en el programa (se almacenarn en la memoria principal) El formato general de una declaracin es:
nombre:
radio: vocales: vector:
tipo_del_dato
valor(es)
LOS REGISTROS
Num Nombre Descripcin
Constante valor cero Temporal reservado para el ensamblador. Usado al traducir las pseudoinstrucciones. Valores resultantes de funciones y evaluaciones Argumentos para subrutinas. No se preservan a travs de llamadas a subrutinas. Temporales. No se preservan a travs de llamadas de subrutinas, por lo que la rutina que llama debe salvarlos si los quiere conservar. Valores salvados. Una subrutina que los use debe salvar sus valores antes de usarlos, y restaurarlos al salir. Continuacin a los $t0-t7. Temporales. No se preservan a travs de llamadas de subrutinas, por lo que la rutina que llama debe salvarlos si los quiere conservar Reservados para el kernel (manejo de interrupciones) Puntero global. Apunta al medio del bloque de 64K en el segmento de datos estticos Puntero de pila (stack pointer). No se actualiza automticamente. Valor salvado. Puntero de marco. Se preserva a travs de llamadas. Permite acceder de modo indexado a los elementos de la pila. Direccin de retorno (return address). 10
11
EL ACCESO A MEMORIA
El ancho del bus de datos es de tamao word (32 bits) El ancho del bus de direcciones es tambin de 32 bits, de lo cual podemos concluir que:
existen 232 direcciones de memoria diferentes de 1 byte de tamao. lo que significan que habr 230 words que son 4 GB
La forma en la que est organizada la memoria es bigendian. Esto significa que cada word tiene la direccin del byte ms significativo de los 4 que forman el word. De esto se puede concluir que la direccin de cada word tiene que ser mltiplo de 4.
12
13
Si un registro contiene una direccin de memoria, podemos usar el contenido de esa direccin de memoria usando parntesis alrededor del registro. Ejemplo: lw $t1, ($t0) # carga en $t1 el valor contenido en la
# direccin de memoria apuntada por $t0
Para acceder a direcciones de memoria consecutivas podemos usar direccionamiento base + desplazamiento (offset). Ejemplo:
lw $t2, 4($t0) # carga en $t2 el valor contenido en la direccin # de memoria apuntada por $t0+4. En este caso como # un word son 4 bytes, en $t2 tendramos el word de # memoria siguiente al apuntado por $t0
14
15
Suma:
add $t0,$t1,$t2 addi $t0,$t3, 7 addu $t1,$t6,$t7 # # # # $t0=$t1+$t2 suman enteros con signo. Negativos representados en complemento a 2. $t0=$t3+7 (o cualquier valor inmediato) $t1=$t6+$t7 suman como enteros sin signo
Resta:
sub $t2,$t3,$t4 subu $t1,$t6,$t7 # $t2=$t3-$t4 resta de enteros # $t1=$t6-$t7 resta como enteros sin signo
Multiplicacin:
mult $t3,$t4 # La multiplicacin de dos registros de 32 bits da # un registro de 64 bits que ser ((Hi,Lo) # Lo = $t5/$t6 (divisin entera) # Hi= $t5 mod $t6 (Hi tendr el resto) # $t2 = $t3 # $t0 = Hi para los resultados de multip y divis. # $t1 = Lo para los resultados de multip y divis.
Divisin:
div $t5,$t6
16
OPERACIONES DE SALTO
Saltos incondicionales:
j etiqueta # salta a la parte del cdigo que empiece con etiqueta: b etiqueta # salta a la parte del cdigo que empiece con etiqueta: jr $t3 # salta a la direccin de programa contenida en $t3
Saltos condicionales:
beq blt ble bgt bge bne $t0,$t1,etiqueta $t0,$t1,etiqueta $t0,$t1,etiqueta $t0,$t1,etiqueta $t0,$t1,etiqueta $t0,$t1,etiqueta # # # # # # si si si si si si $t0=$t1 entonces salta a etiqueta: $t0<$t1 entonces salta a etiqueta: $t0<=$t1 entonces salta a etiqueta: $t0>$t1 entonces salta a etiqueta: $t0>=$t1 entonces salta a etiqueta: $t0<>$t1 entonces salta a etiqueta:
17
18
$v0
1 2 3 4 5 6 7 8
Argumentos
$a0 = entero a imprimir $f12 = flotante a imprimir $f12-13 = double a imprimir $a0 = direccion de memoria de la cadena a imprimir
Resultados
$v0 = entero que se ley $f0 = flotante que se ley $f0-$f1 = double que se ley $a0 = direccin memoria donde se almacenar la cadena a leer. $a1 = nmero. tamao de la cadena $a0 = n bytes requeridos de memoria dinmica $v0 = direccin de memoria que contendr los bytes 19
sbrk
exit
10
La funcin sbrk sirve para solicitar memoria de forma dinmica. Busca n bytes (indicados por $a0) libres consecutivos y devuelve la direccin del primer byte libre en $v0. (NOTA: buscar si hay alguna manera de liberar el
espacio dinmico)
La funcin exit hace un que un programa termine de forma inmediata.
20
21
SUBPROGRAMAS
Los subprogramas son piezas de cdigo que pueden ser invocados desde diferentes partes del programa principal o desde otra subrutina. Los principales motivos para hacer subprogramas son: descomposicin de un problema en problemas ms simples, o bien reutilizacin de cdigo. Lo habitual es que se definan con argumentos de entrada (recogidos en los registros que van desde $a0 a $a3) que variarn el comportamiento del subprograma en funcin de sus valores. Si el resultado de las operaciones se traduce en un valor que tiene que devolver se llama funcin. Si el resultado es la ejecucin de una serie de operaciones sin devolver un valor de manera explcita se llama procedimiento. General a todos los subprogramas: habr un punto de entrada que se explicitar con una etiqueta y una sentencia de retorno, que devolver el control del programa a la instruccin siguiente desde la que se invoc al subprograma.
22
SUBPROGRAMAS
En la invocacin y ejecucin de subprogramas se suelen llevar a cabo las siguientes acciones Se cargan los registros $a0-$a3 (tantos como sean necesarios) con los valores de los argumentos, o bien se cargan los parmetros que se requieran en la pila (se ver en un ejemplo) Se llama a la subrutina: jal etiqueta_subprg (esta instruccin no solo realiza un salto a la etiqueta especificada, sino que fija la direccin de retorno a la subrutina en la siguiente instruccin que debera ejecutar, es decir $ra <- PC+4 ya que las instrucciones mips ocupan 4 bytes) Hay que reservar espacio suficiente en la pila para las variables locales (si no da con los registros temporales). Ejecutar las instrucciones del subprograma. Si emite resultados explcitos (funciones) se devolvern en los registros $v0, $v1. Si con esto no fuera suficiente se deberan dejar los resultados en la cabecera de la pila. Devolver el control a la funcin llamadora, lo que corresponde con la ejecucin de la instruccin jr $ra
1.
2.
3. 4. 5.
6.
23
El subprograma invocado (el que es llamado) obviamente podr modificar los registros $v0 y $v1 ya que es aqu donde se devuelven 24 los resultados explcitos
25
26
27
Significado Comentario
$f2=$f4+$f6 $f2=$f4-$f6 $f2=$f4*$f6 $f2=$f4/$f6 $f2=$f4+$f6 $f2=$f4-$f6 $f2=$f4*$f6 $f2=$f4/$f6 Suma PF. Precisin simple Resta PF. Precisin simple Multiplicacin PF. Precisin simple Divisin PF. Precisin simple Suma PF. Precisin doble Resta PF. Precisin doble Multiplicacin PF. Precisin doble Divisin PF. Precisin doble 29
Significado
$f1=Mem[$t2+100] Mem[$t2+100]=$f1 $f4 = $f6 $f4 = $f6 $f0 = $t0
Comentario
Carga en $f1 la dir. especificada Almacena en la dir. especificada el flotante almacenado en $f1 Mueve datos entre registros punto flotante de precisin simple Mueve datos entre registros punto flotante de precisin doble Es una copia cruda no pasa a flotante. Ojo porque el orden de los operandos no es el de convenio. Igual que antes es copia cruda. Ojo con el orden. 30
mfc1 $t0,$f0
$t0 = $f0
Significado
If (cond==1) go to etiqueta If (cond==0) go to etiqueta If ($f2==$f4) cond =1 else cond =0 If ($f2==$f4) cond =1 else cond =0
Comentario
Salto condicional si cond es cierto Salto condicional si cond es falso Comparacin en precisin simple. Pone cond a 1 o a 0. Comparacin en precisin doble. Pone cond a 1 o a 0.
Ejemplo:
c.eq.s $f2,$f4 bc1t exit: exit
31 # salta a la etiqueta exit si $f2==$f4
$f6, var1
# $f6=0.65
Las nuevas versionas si que dejan hacer cargas en simple y doble precisin con li.s y li.d
li.s $f4,0.65 # $f4 = 0.65
La letra despus de cvt. Dice el tipo al que convierte, en este caso es simple s. La ltima letra dice el tipo desde el que convierte, en este caso entero w. Si hubira una d significa double. Ejemplo de uso:
li $t0,32 mtc1 $t0,$f2 cvt.s.w $f4,$f2 # $t0 = 32 # $f2 = 32 # $f4 = 32.0
32
33
34
35
36
37
38