Está en la página 1de 14

Estructuras de Computadores I Tarea 02 02/99

1. Dada la secuencia de bits:

0011 0100 0101 0101 0100 0011 0100 0010

Qué representa, asumiendo que es:


a. Un número entero en complemento dos.
b. Fracción en complemento dos
c. Un entero sin signo
d. Un punto flotante precisión simple.
e. Una instrucción MIPS (usar nombres simbólicos para los registros)
Puntos b, c, d para más adelante.

2. Lazo en MIPS.
Asuma que al inicio los registro que requieren estar inicializados, tienen valor 0, antes de ingresar al
lazo. Suponga también que el lazo pueda ser ejecutado, al menos cinco veces, de tal forma que algunos
registros podría requerir ser salvados (antes de invocar) y luego restaurados (después del retorno de la
subrutina). Esto debido a que existe un llamado a una subrutina, en el medio del lazo, y que esta
subrutina podría sobreescribir en alguno de los registros.
Escribir el código para salvar y restaurar, para ello es preciso analizar cuidadosamente el código antes y
después del "jal".

Loop: add $t1, $t3, $s0


lw $a1, 4($t1)
slt $t2, $0, $a1
beq $t2, $0, Exit
addi $a0, $a0, 1
lw $a2, 0($s1)
lw $a3, 8($sp)
.
.
.
jal HaceAlgo
.
.
.
add $t4, $v0, $t4
lw $t5, 0($v1)
add $t4, $t5, $t4
addi $t3, $t3, -4

1
ELO311 Tarea 02 02/99

addi $t0, $t0, -1


slti $t6, $t0, 5
beq $t6, $0, Loop
Exit:
3. Ensamblar a mano, el siguiente código. Asumir el inicio de la zona de texto en 0x00400000.
Comprobar los valores de los campos mediante el simulador.
(El nombre main permite al simulador, con trap-handler, llamar al programa main.)

main: sub $t0, $0, $0


addi $t1, $t0, 1
lui $t6, 0xffff
ori $t6, $t6, 0xffff
andi $t5, $t6, 0x5ca3
Loop: slt $t4, $t5, $t1
bne $t4, $0, End
sll $t1, $t1, 1
j Loop
End: add $v0, $t1, $0
jr $ra

Expresar en hexadecimal.
Obs. El simulador ensambla mal los direccionamientos de los branch. La forma correcta de efectuarlos
es tomando la dirección de la instrucción siguiente al branch, y a esta dirección sumarle el número con
signo establecido en el campo inmediato. Además considerar que el úmero es de instrucciones y no de
bytes.

Solución 1.

1. Dada la secuencia de bits:

00110100010101010100001101000010

Qué representa , asumiendo que es :

a. Un número entero en complemento dos.

Respuesta:

En este caso, por comenzar con cero la secuencia,se trata de un numero entero positivo.Para llegar a
conocer este número, primero pasamos la secuencia a su equivalente hexadecimal, para luego
transformarlo a entero equivalente decimal; el procedimiento se muestra a continuación:

2
ELO311 Tarea 02 02/99

Secuencia: 0011 0100 0101 0101 0100 0011 0100 0010


Hexadecimal: 3 4 5 5 4 3 4 2
Decimal: 878003010

e. Una instrucción MIPS, (usando nombres simbólicos para los registros):

Respuesta:

Nos fijamos primero en los 6 primeros bits:

001101: correspnde al código de instrucción ori. Estamos entonces en el formato I .

Los 5 bits siguientes, corresponden al registro rs:

00010: corresponde al registro $v0

Los siguientes 5 bits, son para el registro rt:

10101: corresponde al registro $s5.

Los 16 bits siguientes, corresponden a la dirección inmediata, cuyo equivalente decimal , se


incluye en la instrucción:

0100001101000010: su equivalente decimal es 17218, y su equivalente hexadecimal es: 4342

La instrucción entonces, es la que se muestra a continuación:

Ori $s5,$v0,0x4342

Lo que se muestra a continuacion, es la estructura del formato I, especificamente para nuestro ejemplo:

Nombre formato op rs rt dir. Inmediata


Ori I 001101 00010 10101 0100001101000010
13 2 21 17218 (decimal)

3
ELO311 Tarea 02 02/99

2.- En el programa existen algunos registros que como son temporales del lazo, deben ser guardados.
Estos registros son : $t0, $t3, $t4.
Además conviene guardar la información que está en el stack pointer y en el registro $ra, por si
se modifican dentro de la subrutina.
Hay registros auxiliares y otros que sirven para pasar los parámetros, que no se justifica
guardarlos porque son parte de los valores que se alteran.

.text
.globl main
main:

Loop: add $t1, $t3, $s0


lw $a1, 4($t1)
slt $t2, $0, $a1
beq $t2, $0, Exit
addi $a0, $a0, 1
lw $a2, 0($s1)
lw $a3, 8($sp)
subu $sp,$sp,24
sw $ra,4($sp)
sw $fp,8($sp)
sw $t0,12($sp)
sw $t3,16($sp)
sw $t4,20($sp)
addu $fp,$sp,24

jal HaceAlgo

lw $ra,4($sp)
lw $fp,8($sp)
lw $t0,12($sp)
lw $t3,16($sp)
lw $t4,20($sp)
addu $sp,$sp,24
add $t4, $v0, $t4
lw $t5, 0($v1)
add $t4, $t5, $t4
addi $t3, $t3, -4
addi $t0, $t0, -1
slti $t6, $t0, 5
beq $t6, $0, Loop

4
ELO311 Tarea 02 02/99

3. Ensamblar a mano, el siguiente código. Asumir el inicio de la zona de texto en 0x00400000.


Comprobar los valores de los campos mediante el simulador.
(El nombre main permite al simulador, con trap-handler, llamar al programa main.)

main: sub $t0, $0, $0


addi $t1, $t0, 1
lui $t6, 0xffff
ori $t6, $t6, 0xffff
andi $t5, $t6, 0x5ca3
Loop: slt $t4, $t5, $t1
bne $t4, $0, End
sll $t1, $t1, 1
j Loop
End: add $v0, $t1, $0
jr $ra

Expresar en hexadecimal.
Obs. El simulador ensambla mal los direccionamientos de los branch, sino se emplea el modi bare-
machine.
La forma correcta de efectuarlos es tomando la dirección de la instrucción siguiente al branch, y a ésta
dirección sumarle el número con signo establecido en el campo inmediato. Además considerar que el
número es de instrucciones y no de bytes.
Ensamblando a mano:

0x00004022 sub $t0, $0, $0


0x21090001 addi $t1, $t0, 1
0x3c0effff lui $t6, 0xffff
0x35ceffff ori $t6, $t6, 0xffff
0x31cd5ca3 andi $t5, $t6, 0x5ca3
0x01a9602a slt $t4, $t5, $t1
0x15800002 bne $t4, $0, End
0x00094840 sll $t1, $t1, 1
0x08100005 j Loop
[0x01201020 add $v0, $t1, $0
0x03e00008 jr $ra

Observando el simulador Spim una vez cargado el programa mostrado(sin trap-handler):

[0x00400000] 0x00004022 sub $8, $0, $0 ; 3: sub $t0, $0, $0


[0x00400004] 0x21090001 addi $9, $8, ; 4: addi $t1, $t0, 1
[0x00400008] 0x3c0effff lui $14, -1 ; 5: lui $t6, 0xffff

5
ELO311 Tarea 02 02/99

[0x0040000c] 0x35ceffff ori $14, $14, -1 ; 6: ori $t6,$t6,0xffff


[0x00400010] 0x31cd5ca3 andi $13, $14, 23715 ; 7: andi $t5,$t6,0x5ca3
[0x00400014] 0x01a9602a slt $12, $13, $9 ; 8: slt $t4, $t5, $t1
[0x00400018] 0x15800003 bne $12, $0, 12; ;9: bne $t4, $0, End
[End-0x00400018]
[0x0040001c] 0x00094840 sll $9, $9, 1 ; 10: sll $t1, $t1, 1
[0x00400020] 0x08100005 j 0x00400014 [Loop] ; 11: j Loop
[0x00400024] 0x01201020 add $2, $9, $0 ; 12: add $v0, $t1, $0
[0x00400028] 0x03e00008 jr $31 ; 13: jr $ra

Se puede apreciar claramente el error que comete el simulador Spim ( lo que está marcado con
rojo), siendo correcta la instrucción que fue ensamblada a mano y está marcada con verde.

Solución 2.

1. Dada la secuencia de bits: 0011 0100 0101 0101 0100 0011 0100 0010

a) El número entero en complemento dos que representa es:

(+) 2+4·16+3·256+4·163+5·164+5·165+4·166+3·167 = 878003010

El signo positivo lo da el bit más significativo, ya que es un cero.

b) La instrucción MIPS que representa es: (se utilizó la tabla para ensamblar instrucciones del manual
del programador)

001101 00010 10101 0100 0011 0100 0010

Los primeros 6 dígitos indican la operación: ori


Los siguientes cinco corresponden a Fte1: $2 ($v0)
Los siguientes cinco corresponden a Dst: $21 ($s5)
Los restantes 16 corresponden a Inm16: 0x4342 = 17218 dec

Si consideramos que la sintaxis para la instrucción ori es: ori Dst, Fte1, Inm16 , entonces
llegamos a que la secuencia de bits en cuestión corresponde a la instrucción:

ori $s5 , $v0 , 17218

2. Quisimos realizar una primera aproximación con los conocimientos obtenidos a la fecha. El desarrollo
logrado es el siguiente:

6
ELO311 Tarea 02 02/99

Se entiende del enunciado que se desea hacer un programa que salve y otro que luego restaure
ciertos registros. En particular t1, a1, t2, a0, a2, a3.
Se supone que fP debe apuntar al inicio del segmento de datos en el stack, disponible a la
función.
Deseamos guardar seis registros. Como éstos son de 32 bits, necesitamos 6 palabras o
equivalentemente 24 bytes.
El stack crece hacia direcciones más bajas.

Los códigos para salvar y para restaurar los registros son, respectivamente:

Salvar: subre $sp, $sp, 24


sw $t1, 0($sp)
sw $a1, 4($sp)
sw $t2, 8($sp)
sw $a0,12($sp)
sw $a2, 16($sp)
sw $a3, 20($sp)
sw $fp, -4($sp)

Restaurar: addi $sp , $fp, 4


lw $t1, 0($sp)
lw $a1, 4($sp)
lw $t2, 8($sp)
lw $a0,12($sp)
lw $a2, 16($sp)
lw $a3, 20($sp)
addre $sp, $sp, 24

7
ELO311 Tarea 02 02/99

3. Ensamblar a mano el siguiente código:

main: sub $t0, $0, $0


addi $t1, $t0, 1
lui $t6, 0xffff
ori $t6, $t6, 0xffff
andi $t5, $t6, 0x5ca3
Loop: slt $t4, $t5, $t1
bne $t4, $0, End
sll $t1, $t1, 1
j Loop
End: add $v0, $t1, $0
jr $ra

Utilizando el manual del programador, se ensamblaron las instrucciones y el código de máquina


obtenido es el siguiente:

[0x00400000] 000000 00000 00000 01000 00000 100010


0x 00004022
[0x00400004] 001000 01000 01001 0000 0000 0000 0001
0x 21090001
[0x00400008] 001111 00000 01110 1111 1111 1111 1111
0x 3c0effff
[0x0040000c] 001101 01110 01110 1111 1111 1111 1111
0x 35ceffff
[0x00400010] 001100 01110 01101 0101 1100 1010 0011
0x 31cd5ca3
[0x00400014] 000000 01101 01001 01100 00000 101010
0x 01a 9602 a
[0x00400018] 000101 01100 00000 0000 0000 0000 0002
0x 15800002
[0x0040001c] 000000 00000 01001 01001 00001 000000
0x 00094840
[0x00400020] 000010 0000 0100 0000 0000 0000 0001 01
0x 08100005
[0x00400024] 000000 01001 00000 00010 00000 100000
0x 01201020

8
ELO311 Tarea 02 02/99

Los resultados obtenidos en el simulador son los siguientes:

[0x00400000] 0x00004022 sub $8, $0, $0 ; 6: sub $t0, $0, $0


[0x00400004] 0x21090001 addi $9, $8, 1 ; 7: addi $t1, $t0, 1
[0x00400008] 0x3c0effff lui $14, -1 ; 8: lui $t6, 0xffff
[0x0040000c] 0x35ceffff ori $14, $14, -1 ; 9: ori $t6, $t6, 0xffff
[0x00400010] 0x31cd5ca3 andi $13, $14, 23715 ; 10: andi $t5, $t6, 0x5ca3
[0x00400014] 0x01a9602a slt $12, $13, $9 ; 11: slt $t4, $t5, $t1
[0x00400018] 0x15800003 bne $12, $0, 12 [End-0x00400018]; 12: bne $t4, $0, End
[0x0040001c] 0x00094840 sll $9, $9, 1 ; 13: sll $t1, $t1, 1
[0x00400020] 0x08100005 j 0x00400014 [Loop] ; 14: j Loop

Puede notarse el error de direccionamiento cometido por el simulador (línea destacada). El


ensamblaje correcto de esa instrucción branch es, como se observa en el desarrollo previo:
0x15800002. Esto se advirtió en clases y se debe a que el simulador considera a PC apuntando a una
dirección incorrecta, si no se setea el modo bare-machine.
Luego de esta línea se repiten cíclicamente las últimas 4 instrucciones (debido al salto). Para
lograr tener en bitácora el resto de las instrucciones fue necesario simular una vez más sin el salto a
Loop.
El resultado fue el siguiente:

[0x00400000] 0x00004022 sub $8, $0, $ ; 7: addi $t1, $t0, 1


[0x00400008] 0x3c0effff lui $14, -1 ; 8: lui $t6, 0xffff
[0x0040000c] 0x35ceffff ori $14, $14, -1 ; 9: ori $t6, $t6, 0xffff
[0x00400010] 0x31cd5ca3 andi $13, $14, 23715 ; 10: andi $t5, $t6, 0x5ca3
[0x00400014] 0x01a9602a slt $12, $13, $9 ; 11: slt $t4, $t5, $t1
[0x00400018] 0x15800002 bne $12, $0, 12 [End-0x00400018]; 12: bne $t4, $0, End
[0x0040001c] 0x00094840 sll $9, $9, 1 ; 13: sll $t1, $t1, 1
[0x00400020] 0x01201020 add $2, $9, $0 ; 15: add $v0, $t1, $0
[0x00400024] 0x03e00008 jr $31 ; 16: jr $ra

Se advierte que en esta ocasión el direccionamiento se realiza correctamente.


En todas las demás instrucciones el ensamblaje a mano concuerda con el obtenido en el
simulador.

9
ELO311 Tarea 02 02/99

Solución 3.

1. Dada la secuencia de bits:

0011 0100 0101 0100 0011 0100 0010

Qué representa, asumiendo que es:


a. Un número entero en complemento dos.
b. Una instrucción MIPS (usar nombres simbólicos para los registros)

a) Considerando la secuencia de 32 bits como un número en complemento dos debemos tomar en


cuenta el primer bits (más significativo) como el signo. Debido a que dicho valor es un cero la
secuencia representa un entero positivo, esto implica que (para este caso), los 31 bits menos
significativos se consideran como un entero sin signo (en valor absoluto), dicho valor queda
estructurado de la siguiente forma.

Expresado en hexadecimal:

0 / 011 / 0100 / 0101 / 0101 / 0100 / 0011 / 0100 / 0010


+ / 3 / 4 / 5 / 5 / 4 / 3 / 4 / 2

dicha secuencia equivale al = 0x34554342


Expresado en decimal = 878.003.010

b) Si consideramos la secuencia de 32 bits como una instrucción MIPS:

001101 / 00010 /10101 /0100001101000010

Observando los 6 primeros bits (los mas significativos), y compararlos con los bits de operación de
las distintas instrucciones señaladas en el manual del programador MIPS, se concluye que dicha
secuencia de bits de operación corresponde a la instrucción ori, esta instrucción utiliza el formato I
para ser ensamblada,es decir:

Transferencias: I
Op 6 Rs 5 Rt 5 Inmediato 16

Op = 001101.
Rs = 00010 que equivale al registro $2 = $v0
Rt = 10101 que equivale al registro $21 = $s5
Inmediato 16 = 0100001101000010 que corresponde a la dirección = 0x4342

10
ELO311 Tarea 02 02/99

Finalmente la instrucción queda estructurada de la siguiente forma:

ori $v0, $s0, 0x4342


2 .- Lazo en MIPS

Escribir el código para salvar y restaurar, para ello es preciso analizar cuidadosamente el código antes y
después del “jal”.

Loop: add $t1,$t3,$a0


lw $a1,4($t1)
slt $t2,$0,$a1
beq $t2,$0,Exit
addi $a0,$a0,1
lw $a2,0($s1)
lw $a3,8($sp)

1
jal Hace algo
2

add $t4,$v0,$t4
lw $t5,0($v1)
add $t4,$t5,$t4
addi $t3,$t3,-4
addi $t0,$t0,-1
slti $t6,$t0,5
beq $t6,$0,Loop
Exit:

Es necesario salvar algunos registros antes de invocar la subrutina, para que ésta no escriba sobre ellos,
y al retornar de la subrutina pueda restaurarlos.
Los registros que necesitan ser salvados son los siguientes:
$ t0 : es necesario salvarlo ya que guarda un resultado que será ocupado nuevamente al salir de la
subrutina.
$ t3 : es necesario salvarlo ya que pasa de antes de la subrutina hasta después de ella sin
modificaciones.
$ t4 : al igual que $t0 guarda un resultado y este será ocupado a la salida de la subrutina

11
ELO311 Tarea 02 02/99

No es necesario guardar los demás registros ya que por convenio las funciones trabajan (modifican) los
registros temporales.

1. - Código necesario para salvar los registros:

addi $sp,$sp,-8
sw $t0,0($sp)
sw $t3,4($sp)
sw $t4,8($sp)

Con esto se da el espacio suficiente para guardar estos tres registros en el stack.

2. - Código necesario para restaurar los registros y el stack:

lw $t0,0($sp)
lw $t3,4($sp)
lw $t4,8($sp)
addi $sp,$sp,8

Con esto se restauran los registros y se devuelve el espacio de memoria pedido al stack.

3. Ensamblar a mano, el siguiente código. Asumir el inicio de la zona de texto en 0x00400000.


Comprobar los valores de los campos mediante el simulador.
(El nombre main permite al simulador, con trap-handler, llamar al programa main.)

texto paso dirección

main: sub $t0, $0, $0 #1 0x00400000


addi $t1, $t0, 1 #2 0x00400004
lui $t6, 0xffff #3 0x00400008
ori $t6, $t6, 0xffff #4 0x0040000C
andi $t5, $t6, 0x5ca3 #5 0x00400010
Loop: slt $t4, $t5, $t1 #6 0x00400014
bne $t4, $0, End #7 0x00400018
sll $t1, $t1, 1 #8 0x0040001C
j Loop #9 0x00400020
End: add $v0, $t1, $0 #10 0x00400024
jr $ra #11 0x00400028

12
ELO311 Tarea 02 02/99

Para ensamblar a mano este código nos basamos en los diferentes formatos que pueden tener las
instrucciones:

Operaciones. R
Op 6 Rs 5 Rt 5 Rd 5 Shamn 6 Funct 5

Transferencias: I
Op 6 Rs 5 Rt 5 Inmediato 16

Saltos: J
Op 6 Dirección 26
Asociando cada registro con su binario equivalente (p.ej. $t0 es el registro 8 = 1000), que en
los jumps el campo de 26 bits se extiende a 32 (4 los saca del primer dígito hexadecimal del PC el
cual es cero y los dos restantes también del PC, considerando que todas las direcciones son múltiplos
de 4) y ayudados por el manual de programación MIPS, podemos representar el código de la siguiente
manera:

Paso & dirección formato código binario instrucción

#1 main: sub $t0, $0, $0 R 000000 00000 00000 01000 00000 100010 0x00004022

#2 addi $t1, $t0, 1 I 001000 01000 01001 0000 0000 0000 0001 0x21900001

#3 lui $t6, 0xFFFF I 001111 00000 01110 1111 1111 1111 1111 0x3C0EFFFF

#4 ori $t6, $t6, 0xFFFF I 001101 01110 01110 1111 1111 1111 1111 0x35CEFFFF

#5 andi $t5, $t6, 0x5CA3 I 001100 01110 01110 1111 1111 1111 1111 0x31CD5CA3

#6 Loop: slt $t4, $t5, $t1 R 000000 01101 01001 01100 00000 101010 0x01A9602A

#7 bne $t4, $0, End I 000101 01100 00000 0000 0000 0000 0010 0x15800002

#8 sll $t1, $t1, 1 RI 000000 00000 01001 01001 00001 000000 0x00094840

#9 j Loop J 000010 0000 0100 0000 0000 0000 0001 01 0x08100005

#10 End: add $v0, $t1, $s0 R 000000 01001 00000 00010 00000 100000 0x01201020

#11 jr $ra R 000000 11111 00000 00000 00000 000100 0x03E00008

13
ELO311 Tarea 02 02/99

Ejemplo de ensamblaje:

Formato R:
#6 Loop slt $t4, $t5, $t1
- El OP = 000000
- RS: fuente 1= $t5 = registro número 13 = 01101
- RT: fuente 2= $t1 = registro número 9 = 01001
- RD: destino = $t4 = registro número 12 = 01100
- Shamt = 00000
- Funct =101010

La instrucción queda entonces: 000000 01101 01001 01100 00000 101010

En hexadecimal: 0000 / 0001 / 1010 / 1001 / 0110 / 0000 / 0010 / 1010


0x 0 1 A 9 6 0 2 A

14

También podría gustarte