Estructuras de Computadores I Tarea 02 02/99 1. Dada la

Transcrição

Estructuras de Computadores I Tarea 02 02/99 1. Dada la
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
lw
slt
beq
addi
lw
lw
jal
add
lw
add
addi
$t1, $t3, $s0
$a1, 4($t1)
$t2, $0, $a1
$t2, $0, Exit
$a0, $a0, 1
$a2, 0($s1)
$a3, 8($sp)
.
.
.
HaceAlgo
.
.
.
$t4, $v0, $t4
$t5, 0($v1)
$t4, $t5, $t4
$t3, $t3, -4
1
ELO311
Tarea 02
addi
slti
beq
02/99
$t0, $t0, -1
$t6, $t0, 5
$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:
Loop:
End:
sub
addi
lui
ori
andi
slt
bne
sll
j
add
jr
$t0, $0, $0
$t1, $t0, 1
$t6, 0xffff
$t6, $t6, 0xffff
$t5, $t6, 0x5ca3
$t4, $t5, $t1
$t4, $0, End
$t1, $t1, 1
Loop
$v0, $t1, $0
$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
Ori
I
op
rs
rt
001101 00010 10101
13
2
21
dir. Inmediata
0100001101000010
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
lw
slt
beq
addi
lw
lw
subu
sw
sw
sw
sw
sw
addu
jal
lw
lw
lw
lw
lw
addu
add
lw
add
addi
addi
slti
beq
$t1, $t3, $s0
$a1, 4($t1)
$t2, $0, $a1
$t2, $0, Exit
$a0, $a0, 1
$a2, 0($s1)
$a3, 8($sp)
$sp,$sp,24
$ra,4($sp)
$fp,8($sp)
$t0,12($sp)
$t3,16($sp)
$t4,20($sp)
$fp,$sp,24
HaceAlgo
$ra,4($sp)
$fp,8($sp)
$t0,12($sp)
$t3,16($sp)
$t4,20($sp)
$sp,$sp,24
$t4, $v0, $t4
$t5, 0($v1)
$t4, $t5, $t4
$t3, $t3, -4
$t0, $t0, -1
$t6, $t0, 5
$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:
Loop:
End:
sub
addi
lui
ori
andi
slt
bne
sll
j
add
jr
$t0, $0, $0
$t1, $t0, 1
$t6, 0xffff
$t6, $t6, 0xffff
$t5, $t6, 0x5ca3
$t4, $t5, $t1
$t4, $0, End
$t1, $t1, 1
Loop
$v0, $t1, $0
$ra
Expresar en hexadecimal.
Obs. El simulador ensambla mal los direccionamientos de los branch, sino se emplea el modi baremachine.
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
0x21090001
0x3c0effff
0x35ceffff
0x31cd5ca3
0x01a9602a
0x15800002
0x00094840
0x08100005
[0x01201020
0x03e00008
sub
$t0, $0, $0
addi
$t1, $t0, 1
lui
$t6, 0xffff
ori
$t6, $t6, 0xffff
andi
$t5, $t6, 0x5ca3
slt
$t4, $t5, $t1
bne
$t4, $0, End
sll
$t1, $t1, 1
j
Loop
add $v0, $t1, $0
jr
$ra
Observando el simulador Spim una vez cargado el programa mostrado(sin trap-handler):
[0x00400000]
[0x00400004]
[0x00400008]
0x00004022 sub $8, $0, $0
0x21090001 addi $9, $8,
0x3c0effff lui $14, -1
; 3: sub
; 4: addi
; 5: lui
$t0, $0, $0
$t1, $t0, 1
$t6, 0xffff
5
ELO311
Tarea 02
[0x0040000c]
[0x00400010]
[0x00400014]
[0x00400018]
[0x0040001c]
[0x00400020]
[0x00400024]
[0x00400028]
02/99
0x35ceffff ori $14, $14, -1
; 6: ori
0x31cd5ca3 andi $13, $14, 23715
; 7: andi
0x01a9602a slt $12, $13, $9
; 8: slt
0x15800003 bne $12, $0, 12;
;9: bne
[End-0x00400018]
0x00094840 sll $9, $9, 1
; 10: sll
0x08100005 j 0x00400014 [Loop]
; 11: j
0x01201020 add $2, $9, $0
; 12: add
0x03e00008 jr $31
; 13: jr
$t6,$t6,0xffff
$t5,$t6,0x5ca3
$t4, $t5, $t1
$t4, $0, End
$t1, $t1, 1
Loop
$v0, $t1, $0
$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:
Los siguientes cinco corresponden a Fte1:
Los siguientes cinco corresponden a Dst:
Los restantes 16 corresponden a Inm16:
ori
$2 ($v0)
$21 ($s5)
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:
Loop:
End:
sub
addi
lui
ori
andi
slt
bne
sll
j
add
jr
$t0, $0, $0
$t1, $t0, 1
$t6, 0xffff
$t6, $t6, 0xffff
$t5, $t6, 0x5ca3
$t4, $t5, $t1
$t4, $0, End
$t1, $t1, 1
Loop
$v0, $t1, $0
$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]
[0x00400004]
[0x00400008]
[0x0040000c]
[0x00400010]
[0x00400014]
[0x00400018]
[0x0040001c]
[0x00400020]
0x00004022 sub $8, $0, $0
; 6: sub
$t0, $0, $0
0x21090001 addi $9, $8, 1
; 7: addi
$t1, $t0, 1
0x3c0effff lui $14, -1
; 8: lui
$t6, 0xffff
0x35ceffff ori $14, $14, -1
; 9: ori
$t6, $t6, 0xffff
0x31cd5ca3 andi $13, $14, 23715
; 10: andi
$t5, $t6, 0x5ca3
0x01a9602a slt $12, $13, $9
; 11: slt
$t4, $t5, $t1
0x15800003 bne $12, $0, 12 [End-0x00400018]; 12: bne
$t4, $0, End
0x00094840 sll $9, $9, 1
; 13: sll
$t1, $t1, 1
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]
[0x00400008]
[0x0040000c]
[0x00400010]
[0x00400014]
[0x00400018]
[0x0040001c]
[0x00400020]
[0x00400024]
0x00004022 sub $8, $0, $
; 7: addi
$t1, $t0, 1
0x3c0effff lui $14, -1
; 8: lui
$t6, 0xffff
0x35ceffff ori $14, $14, -1
; 9: ori
$t6, $t6, 0xffff
0x31cd5ca3 andi $13, $14, 23715
; 10: andi
$t5, $t6, 0x5ca3
0x01a9602a slt $12, $13, $9
; 11: slt
$t4, $t5, $t1
0x15800002 bne $12, $0, 12 [End-0x00400018]; 12: bne
$t4, $0, End
0x00094840 sll $9, $9, 1
; 13: sll
$t1, $t1, 1
0x01201020 add $2, $9, $0
; 15: add
$v0, $t1, $0
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
lw
slt
beq
addi
lw
lw
$t1,$t3,$a0
$a1,4($t1)
$t2,$0,$a1
$t2,$0,Exit
$a0,$a0,1
$a2,0($s1)
$a3,8($sp)
1
jal
Hace algo
2
add
lw
add
addi
addi
slti
beq
Exit:
$t4,$v0,$t4
$t5,0($v1)
$t4,$t5,$t4
$t3,$t3,-4
$t0,$t0,-1
$t6,$t0,5
$t6,$0,Loop
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
sw
sw
sw
$sp,$sp,-8
$t0,0($sp)
$t3,4($sp)
$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
lw
lw
addi
$t0,0($sp)
$t3,4($sp)
$t4,8($sp)
$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
main:
Loop:
End:
sub
addi
lui
ori
andi
slt
bne
sll
j
add
jr
paso
$t0, $0, $0
$t1, $t0, 1
$t6, 0xffff
$t6, $t6, 0xffff
$t5, $t6, 0x5ca3
$t4, $t5, $t1
$t4, $0, End
$t1, $t1, 1
Loop
$v0, $t1, $0
$ra
#1
#2
#3
#4
#5
#6
#7
#8
#9
#10
#11
dirección
0x00400000
0x00400004
0x00400008
0x0040000C
0x00400010
0x00400014
0x00400018
0x0040001C
0x00400020
0x00400024
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
Transferencias: I
Op 6
Rs 5
Rt 5
Inmediato 16
Shamn 6
Funct 5
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
RS: fuente 1= $t5 = registro número 13
RT: fuente 2= $t1 = registro número 9
RD: destino = $t4 = registro número 12
Shamt
Funct
La instrucción queda entonces:
En hexadecimal:
0x
= 000000
= 01101
= 01001
= 01100
= 00000
=101010
000000 01101 01001 01100 00000 101010
0000 / 0001 / 1010 / 1001 / 0110 / 0000 / 0010 / 1010
0
1
A
9
6
0
2
A
14

Documentos relacionados