Está en la página 1de 9

ENSAMBLADOR:

PROGRAMACIN EN ENSAMBLADOR

Estructura de Computadores, grupo 5.


Hctor Bordajandi Molen, DNI 48722797B.
borda@openmailbox.org
ndice
Archivos adjuntos

Introduccin

Parte 1

Parte 2

Parte 3

Archivos adjuntos
Con la memoria se adjuntan los tres .asm correspondientes a cada parte del proyecto. Se adjunta
un documento de hoja de clculo de LibreOffice, en el que se han obtenido los valores .numero de la
prctica 3.

Introduccin:
Se considera finalizada la parte ms terica introductiva del MIPS. Esta prctica se centra en la
aplicacin de conocimientos ya adquiridos, centrndose en la interaccin con perifricos.
No se introducen nuevos trminos ni mtodos de programacin, la finalidad en esta ocasin es
experimentar con lo ya aprendido sobre la herramienta Digital Lab Sim que por defecto incluye la API
MARS. Accedemos a ella por medio del men Tools Digital Lab Sim.
Digital Lab Sim:
Esta herramienta consiste en una simulacin de un display de dos cifras, cada una de 7
segmentos. Cada display es accesible por medio de una direccin de memoria predefinida. Cada
segmento es activado o desactivado por medio de los valores de los bits en dicha memoria (0 apagado,
1 encendido), correspondiendo cada segmento a un bit. Adems de 7 segmentos, cada cifra tiene un
punto decimal activable.
Durante el transcurso de la prctica, nos referiremos a los diferentes segmentos con una letra
asociada nica, indicando previamente si es perteneciente a la cifra o display 1 o al 2 (viene dada por la
direccin de memoria). Las letras asociadas a los segmentos son las siguientes:

Parte 1:
En el .pdf de la prctica se adjunta un fragmento de cdigo del cual se pide su ejecucin y
anlisis de esta, y una posterior modificacin para que muestre el numero 80. El fragmento es el
siguiente:
# Ejemplo displays del perifrico Digital Lab Sim
.text
main:
li $s0, 0xFFFF0010 # carga direccin base del display derecho
li $s1, 0xFFFF0011 # carga direccin base del display izquierdo
li $t1, 0x01 # El bit 0 activa el segmento A
sb $t1, 0($s0) # almacena en direccin del display derecho el
valor de $t1
li $t1, 0x80 # El punto decimal
sb $t1, 0($s1) # almacena en direccin del display izquierdo el
valor de $t1
li $v0, 10
syscall
El resultado de la ejecucin era de esperar, puesto que los comentarios describen claramente el
programa:
Para mostrar el numero 80 por display, el cdigo es modificado tal como se muestra a
continuacin en las lneas en negrita:
# Ejemplo displays del perifrico Digital Lab Sim
.text
main:
li $s0, 0xFFFF0010 # carga direccin base del display derecho
4

li $s1, 0xFFFF0011 # carga direccin base del display izquierdo


li $t1, 0x0000003F # Activamos A, B, C, D, E, F
sw $t1, ($s0)
li $t1, 0x0000007F # Como en el caso anterior, pero tambien activamos G
sb $t1, ($s1)
li $v0, 10
syscall

Parte 2:
Se pide que una serie de segmentos se visualicen consecutivamente. Despues se debe crear un
bucle que repita dicha secuencia.
# Ejemplo displays del perifrico Digital Lab Sim
.text
main:
li $s0, 0xFFFF0010 # carga direccin base del display derecho
li $s1, 0xFFFF0011 # carga direccin base del display izquierdo
li $t1, 0x01 # Se carga A
sb $t1, 0($s0) # Se activa A en display derecho
sb $t1, 0($s1) # Se activa A en display izquierdo
li $t1, 0x21 # Se carga A y F
sb $t1, 0($s1) # Activados A y F en display izquierdo
li $t1, 0x31 # A, F y D panel izquierdo
sb $t1, 0($s1) #
li $t1, 0x39
sb $t1, 0($s1)
li $t1, 0x09
sb $t1, 0($s0)
li $t1, 0x0D
sb $t1, 0($s0)
li $t1, 0x0f
sb $t1, 0($s0)
li $v0, 10
syscall
A continuacin modularizamos el programa y lo convertimos en un bucle:
# Ejemplo displays del perifrico Digital Lab Sim
.text
main:
li $s0, 0xFFFF0010 # carga direccin base del display derecho
li $s1, 0xFFFF0011 # carga direccin base del display izquierdo
j bucle

bucle:
li $t1, 0x01
sb $t1, 0($s0)
li $t2, 0x00
sb $t2, 0($s0)
sb $t1, 0($s1)
li $t1, 0x20
sb $t1, 0($s1)
li $t1, 0x10
sb $t1, 0($s1)
li $t1, 0x08
sb $t1, 0($s1)
sb $t2, 0($s1)
sb $t1, 0($s0)
li $t1, 0x04
sb $t1, 0($s0)
j bucle
Es destacable que, a pesar de que el ejercicio es tal y como manda el enunciado, no resulta muy,
puesto que no hay salida posible.
Parte 3:
En este ltimo problema, el display del TOOLS pasa a tener un papel secundario en un
programa ms complejo: deber usarse para mostrar un array previamente introducido por el usuario, y
que se ha ordenado ascendente o descendentemente, segun eleccin de este.
En primer lugar, en el main, al usuario se le pide el numero de elementos que habr en el vector.
Dicho nmero multiplicado por el tamao de un entero en bits (4) se almacena en un registro, ms tarde
servir para salir de bucles.
Sabiendo el numero de elementos, el vector se llena de la siguiente manera:

llenar:
li $v0, 4
la $a0, texto2
syscall
li $v0, 5
syscall
6

#leemos valor

bltz $v0, llenar


bgt $v0, 99, llenar
move $t1, $v0
sw $t1, vector($t9)
addi $t9, $t9, 4
bne $t9, $t8, llenar

#comprobamos que esta en el rango


#$t9 es igual al numero de elementos entrados * 4
#mientras $t9 no sea el numero deseado de elementos, bucle

Donde se ha almacenado en $t8 el numero de elementos deseados por el usuario, multiplicado


por 4.
Una vez lleno, empieza la ordenacin. El usuario selecciona si la desea de forma ascendente o
descendente.
La ordenacin del vector ha sido la parte sin duda ms interesante (una despedida memorable
del ensamblador y la asignatura). El algoritmo utilizado es el de seleccin, debido a su sencilla
implementacin y el tamao relativamente reducido del vector a ordenar.
El algoritmo de seleccin ordena los elementos del vector uno a uno, cogindolos y
arrastrndolos hasta su posicin correspondiente. Vemoslo con la ordenacin ascendente:
ascendente1:
addi $t0, $t0, 4
bge $t0, $t8, mostrar
add $t1, $t0, $zero
subi $t2, $t1, 4

ascendente2:
lw $t3, vector($t1)
lw $t4, vector($t2)
la $t9, ascendente2
bgt $t3, $t4, swap
subi $t1, $t1, 4
la $t2, -4($t1)
bltz $t2, ascendente1
j ascendente2

#contador del elemento en el que estamos +1


#si hemos llegado al final, esta ordenado
#puntero a elemento i
#puntero a elemento i-1

#Cargamos vector[i] e [i-1]


#si vector[i]>vector[i-1] hacemos swap
#i-#si hemos llegado al principio del array, salimos al bucle exterior

swap:
sw $t3, vector($t2)
sw $t4, vector($t1)
jr $t9
7

#realizamos el swap
#volvemos del sitio que vinimos

$t0 pasar por todos los elementos del vector, empezando por el 2, y marcar en todo momento
la lnea divisoria entre dos conjuntos: El conjunto de elementos ordenados, que ir aumentando durante
la ejecucin, quedar en las direcciones de memoria desde vector[0] hasta vector[$t0], y el conjunto
desordenado original, que ir desde vector[$t0] hasta vector[$t8] y que, cuando acabe la ordenacin,
debe estar vaco.
De ordenar el vector no se encargar $t0, esta funcin la cumplen otros registros y operaciones
en el bucle interior ascendente2. En l, los registros $t1 y $t2, que se inicializan como $t1 = $t0 y $t2 =
$t0-4 (esto es, una posicin atrs) compararn vector[$t0] con vector [$t0 1 posicin]. Entre estos
elementos hay una gran diferencia: vector[$t0] forma parte del conjunto desordenado de elementos,
mientras que el elemento en la posicin anterior est ordenado. Si resulta que el elemento[$t0] no
satisface la ordenacin deseada, ser intercambiado con el elemento [$t0 1 posicin], y volveremos a
ejecutar el mismo bucle, disminuyendo en 1 la posicin de $t1 y $t2.
De esta manera, los valores desordenados son introducidos uno a uno, no introduciendo uno
nuevo hasta que es seguro que el conjunto ordenado est, efectivamente, ordenado tal y como demanda
el usuario.
El vector ya est en memoria ordenado correctamente. A continuacin, se procede a mostrarlo
con el display del TOOLS.
Para ello, se ha creado un vector en .data, que contiene los bytes especficos que, introducidos
en la direccin correspondiente al display, muestran los dgitos decimales. Se encuentran ordenados del
0 al 9:
numeros: .byte 0x3F 0x06 0x5B 0x4F 0x66 0x6D 0x7D 0x07 0x7F 0x6F
El motivo de esta ordenacin es el mtodo de carga de los bytes en las direcciones de los
displays:
mostrar:
#preparamos direcciones
lw $s0, rightd
lw $s1, leftd
addu $t1, $zero, $zero
li $t9, 10
bucle:
#comenzamos a imprimir un elemento por iteracion
lw $t2, vector($t1) #$t2 = vector[$t1]
div $t2, $t9
mflo $t2
sll $t2, $t2, 2
# ($t2 /= 10)<<2
mfhi $t3
sll $t3, $t3, 2
# ($t3 = $t2 % 10)<<2
lw $t0, numeros($t3) #$t0 = numeros[$t3], lo que mostrara por display el valor $t0
lw $t5, numeros($t2) #$t5 = numeros[$t2], mostrando por display $t5
sb $t0, 0($s1)
#guardamos los valores
sb $t5, 0($s0)
8

li $v0, 12
syscall
addi $t1, $t1, 4
blt $t1, $t8, bucle
li $v0, 10
syscall

#siguiente elemento del vector


#Si no hemos pasado el ultimo elemento, se repite el proceso
#fin

Bsicamente, descomponemos cada elemento E en E = 10x+y, y almacenamos los valores


numeros[x] y numeros[y] en los displays izquierdo y derecho, respectivamente. El proceso se repite
tantas veces como elementos haya en el vector.

También podría gustarte