Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las...

26
Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones Santiago E. Felipe/UTM-2019 1 2. Arquitectura del repertorio de instrucciones Para comandar una computadora se le debe “hablar” en su lenguaje. Instrucciones: Palabras del lenguaje. Repertorio de instrucciones: Vocabulario de la computadora. Los lenguajes de máquina son muy similares entre sí porque: Las computadoras se construyen con la misma tecnología de hardware. Hay un número finito de operaciones básicas que todas las máquinas deben considerar. Los diseñadores de computadoras tienen una meta común: Encontrar un lenguaje que simplifique la construcción del hardware y el compilador; mientras se maximiza el rendimiento y minimiza el costo. A lo largo del curso revisaremos la Arquitectura MIPS (MIPS: Microprocessor without Interlocked Pipeline Stages). Un procesador que tiene las características típicas de los procesadores modernos. El procesador MIPS fue diseñado en la Universidad de Stanford, posteriormente fue comercializado por MIPS Technologies ( www.mips.com ). La arquitectura MIPS, similar a ARM, es ampliamente usada como núcleo en el mercado de los sistemas embebidos, encontrándose en aplicaciones de electrónica de consumo, equipo de almacenamiento y redes, cámaras, impresoras, entre otros…. La arquitectura MIPS es del tipo registro-registro, con tres operandos por instrucción. 2.1 Lenguaje ensamblador El diseño de un repertorio de instrucciones debe basarse en principios bien establecidos. MIPS se fundamenta en los 4 principios siguientes: 1. El diseño debe ser simple y regular. La regularidad hace que la implementación sea más simple y la simplicidad permite alcanzar el más alto rendimiento al más bajo costo. 2. Si es más pequeño, es más rápido. Un procesador va a operar a una frecuencia más alta si las señales eléctricas viajan una menor distancia. 3. Favorecer los casos comunes. El procesador debe resolver con fluidez lo que ocurre con mayor frecuencia y dar atención especial a las situaciones poco frecuentes. Por ejemplo, es mucho más frecuente el uso de constantes pequeñas que constantes grandes. 4. Un buen diseño demanda compromisos. Un sistema no puede cubrir todas las expectativas, algunos compromisos deben establecerse durante su diseño.

Transcript of Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las...

Page 1: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 1

2. Arquitectura del repertorio de instrucciones

Para comandar una computadora se le debe “hablar” en su lenguaje.

• Instrucciones: Palabras del lenguaje.

• Repertorio de instrucciones: Vocabulario de la computadora.

Los lenguajes de máquina son muy similares entre sí porque:

• Las computadoras se construyen con la misma tecnología de hardware.

• Hay un número finito de operaciones básicas que todas las máquinas deben considerar.

Los diseñadores de computadoras tienen una meta común:

Encontrar un lenguaje que simplifique la construcción del hardware y el compilador; mientras

se maximiza el rendimiento y minimiza el costo.

A lo largo del curso revisaremos la Arquitectura MIPS (MIPS: Microprocessor without

Interlocked Pipeline Stages). Un procesador que tiene las características típicas de los

procesadores modernos.

El procesador MIPS fue diseñado en la Universidad de Stanford, posteriormente fue

comercializado por MIPS Technologies ( www.mips.com ).

La arquitectura MIPS, similar a ARM, es ampliamente usada como núcleo en el mercado de los

sistemas embebidos, encontrándose en aplicaciones de electrónica de consumo, equipo de

almacenamiento y redes, cámaras, impresoras, entre otros….

La arquitectura MIPS es del tipo registro-registro, con tres operandos por instrucción.

2.1 Lenguaje ensamblador

El diseño de un repertorio de instrucciones debe basarse en principios bien establecidos.

MIPS se fundamenta en los 4 principios siguientes:

1. El diseño debe ser simple y regular. La regularidad hace que la implementación sea

más simple y la simplicidad permite alcanzar el más alto rendimiento al más bajo costo.

2. Si es más pequeño, es más rápido. Un procesador va a operar a una frecuencia más

alta si las señales eléctricas viajan una menor distancia.

3. Favorecer los casos comunes. El procesador debe resolver con fluidez lo que ocurre

con mayor frecuencia y dar atención especial a las situaciones poco frecuentes. Por

ejemplo, es mucho más frecuente el uso de constantes pequeñas que constantes grandes.

4. Un buen diseño demanda compromisos. Un sistema no puede cubrir todas las

expectativas, algunos compromisos deben establecerse durante su diseño.

Page 2: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 2

2.1.1 Operaciones y operandos

Toda computadora debe realizar operaciones aritméticas y lo natural es que incluyan 3

operandos, dos fuentes y un destino (no necesariamente deben ser diferentes).

El hardware para un número fijo de operandos es más simple que el hardware para un

número variable (principio 1).

El repertorio MIPS incluye las instrucciones aritméticas y lógicas básicas:

ADD a, b, c # a = b + c SUB a, b, c # a = b – c AND a, b, c # a = a AND b OR a, b, c # a = a OR c XOR a, b, c # a = a XOR c NOR a, b, c a = NOT (a OR c) SLT a, b, c # a = 1 si b < c, sino a = 0

Ejercicio: Para la siguiente asignación en C:

f = (g + h) – (i + j);

¿Qué producirá el compilador?

Los lenguajes de alto nivel utilizan variables como operandos, durante la compilación, las

variables se asocian con un número especial de localidades llamadas registros.

Los registros son los ladrillos en la construcción de una computadora, se definen durante el

diseño del hardware y quedarán visibles al programador cuando la computadora esté

completada, a pesar de estar dentro de la CPU.

MIPS tiene 32 registros y cada uno es de 32 bits, las instrucciones aritméticas pueden elegir

hasta tres de ellos para sus operandos. La arquitectura es muy regular, porque las

instrucciones también se codifican en palabras de 32 bits (principio 1).

Un programador desearía un número mayor de registros, sin embargo, el desarrollador de

hardware tiene como meta conseguir un ciclo de reloj pequeño (principios 2 y 4).

Los registros son referidos con el símbolo $: $0, $1, $2, … $31, sin embargo, para

simplificar el trabajo del compilador a los diferentes registros se les designan tareas

especiales y se establecen nombres relacionados con cada tarea.

Page 3: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 3

Nombre Registro (s) Uso

$zero 0 Constante con el valor 0

$at 1 Temporal para el ensamblador

$v0 - $v1 2 – 3 Resultados de una función o expresión

$a0 - $a3 4 – 7 Argumentos de una función

$t0 - $t7 8 – 15 Temporales

$s0 - $s7 16 – 23 Registros seguros

$t8 - $t9 25 – 25 Más temporales

$gp 28 Apuntador global

$sp 29 Apuntador de pila

$fp 30 Apuntador de marco

$ra 31 Dirección de retorno

El registro $0 o $zero siempre tiene 0, está protegido por hardware y es útil como una

referencia para comparaciones.

Ejercicio: Empleando los nombres de los registros, ¿Cómo se traduce la sentencia?

f = (g + h) – (i + j);

2.1.2 Acceso a memoria

La memoria es un espacio externo a la CPU con una capacidad de almacenamiento mucho

mayor que los registros, como contra parte del principio 2, si es más grande es más lenta.

La memoria es usada para datos compuestos como: Arreglos, estructuras, datos dinámicos,

etc., físicamente la memoria está organizada por bytes, sin embargo, las palabras están

alineadas y las direcciones son múltiplos de 4.

MIPS utiliza un acceso del tipo Big Endian, significa que el byte más significativo se ubica

en la dirección menos significativa de una palabra.

Para tener acceso a la memoria, el repertorio MIPS incluye las instrucciones:

LW $t0, cte($t1) # $t0 = Mem[$t1 + cte], (carga) SW $t0, cte($t1) # Mem[$t1 + cte] = $t1, (almacenamiento)

Ambas emplean un registro como base y una constante como desplazamiento, para calcular

la dirección efectiva de acceso a memoria.

La memoria se puede ver como un arreglo lineal grande, las instrucciones son capaces de

direccionar hasta 230 palabras de 32 bits (4 GBytes).

Page 4: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 4

Dado que el acceso a registros es más rápido que el acceso a memoria, el compilador debe

asociar las variables con los registros y enviar a memoria sólo a aquellas variables que son

usadas con menor frecuencia o que tienen un tamaño significativo.

Ejercicio: Carga y Almacenamiento.

Para la siguiente asignación en C: A[12] = h + A[8];

¿Qué producirá el compilador? Suponiendo que el comienzo del arreglo A se encuentra en

el registro $s0 y que la variable h se asocia con el registro $s1.

Debe tomarse en cuenta que cada elemento del arreglo ocupa 4 bytes.

Ejercicio: Usando una variable como índice de un arreglo.

La siguiente asignación utiliza a la variable i como índice del arreglo A:

g = h + A[i];

¿Qué producirá el compilador? Suponiendo que el comienzo del arreglo A se encuentra en

el registro $s0, y que las variables g, h e i se asocian con los registros: $s1, $s2 y $s3,

respectivamente.

2.1.3 Instrucciones para tomar decisiones

Las computadoras se distinguen de las calculadoras por su capacidad para tomar decisiones

con base en los datos de entrada. Para ello, la arquitectura MIPS cuenta con dos

instrucciones de brincos condicionales y un salto incondicional:

BEQ $t0, $t1, L1 # Brinco sobre igual BNE $t0, $t1, L1 # Brinco sobre diferente J etiqueta # Salto incondicional JR $t0 # Salto a registro

Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

con la instrucción SLT (ajuste sobre menor que). Las comparaciones sobre igual o diferente

son más comunes que otras como >, <, >= ó <= (principio 3).

Estas instrucciones modifican al PC (Program Counter, Contador de Programa), registro de

propósito especial que contiene la dirección de la instrucción bajo ejecución.

Page 5: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 5

Ejercicios: Traduzca a código MIPS las diferentes secuencias de código en alto nivel:

Código en lenguaje C Consideraciones

if ( i == j ) f = g + h

Las variables f - j deben asociarse con

los registros $s0 - $s4.

if ( i < j ) f = g + h;

else f = g – h;

Las variables f - j deben asociarse con

los registros $s0 - $s4.

do { g = g + A[i]; i = i + j; } while( i != h );

Las variables g - j se asocian con los

registros $s1 - $s4. El registro base para

el arreglo A es $s5.

while (save[i] == k)

i = i + j;

Las variables i - k se asocian con los

registros $s3 - $s5. El registro base para

el arreglo save es $s6.

2.1.4 Manejo de Constantes

Usos típicos de constantes: Incrementar el índice de un arreglo, contar iteraciones en un

lazo, ajustar el apuntador de la pila, etc.

En los programas reales, alrededor del 50 % de operaciones aritméticas involucran el uso

de constantes; por ejemplo, en el compilador gcc el 52 % de operaciones aritméticas se

aplican sobre constantes, en el simulador de circuitos llamado spice este parámetro

corresponde al 69 %.

Si las constantes son muy utilizadas, por qué no favorecer su uso (principio 3).

Algunas de las instrucciones incluidas en el repertorio MIPS, relacionadas con el uso de

constantes son:

ADDI $t0, $t1, cte # $t0 = $t1 + cte ANDI $t0, $t1, cte # $t0 = $t1 AND cte ORI $t0, $t1, cte # $t0 = $t1 OR cte SLTI $t0, $t1, cte # $t0 = 1 si $t1 < cte, sino $t0 = 0 LUI $t0, cte # $t0 = cte << 16

# Cargar inmediato superior Las constantes son de 16 bits, si se requiere el uso de una constante grande se debe emplear

una instrucción Lui seguida de una instrucción Ori.

Page 6: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 6

Ejercicios: Nuevamente se traducirá de alto a bajo nivel:

Código en lenguaje C Consideraciones

x = 0; for( i = 0; i < 10; i++ )

x = x + i;

Las variables i se asociarse con $s0, x

con $s1.

switch ( k ) { case 0: f = i + h; break; case 1: f = g + h; break; case 2: f = g - h; break; case 3: f = i - j; break;

}

Las variables f - k deben asociarse con

los registros $s0 - $s5.

Con la instrucción: La $t0, Label

(load address), se puede obtener la dirección de una etiqueta en el programa. La = Lui + Ori

Los desplazamientos lógicos también involucran constantes, aunque en estos casos la

constante es de 5 bits, suficientes para todos los posibles desplazamientos en un registro de

32 bit. Las instrucciones para desplazamientos son:

SLL $t0, $t1, cte # $t0 = $t1 << cte (izquierda) SRL $t0, $t1, cte # $t0 = $t1 >> cte (derecha)

2.1.5 Manejo de funciones

El manejo de funciones es uno de los aspectos más importantes de la programación

estructurada; por lo que cualquier repertorio de instrucciones soportarlo.

Los pasos que intrínsecamente se realizan al invocar una función son:

a) Se colocan los argumentos en un lugar donde los espera la función.

b) Se transfiere el control a la función, a la vez que se respalda la dirección de retorno.

c) Se adquieren los recursos de almacenamiento necesarios.

d) Se realiza la tarea deseada.

e) Se coloca el valor del resultado en algún lugar donde lo espera la función invocadora.

f) Se libera el espacio destinado para el almacenamiento de recursos.

g) Se regresa el control al punto de origen.

Los registros involucrados en el manejo de funciones son:

• $a0 - $a3: Cuatro registros para los argumentos.

• $v0 - $v1: Dos registros para los valores de retorno.

• $ra: Un registro para almacenar la dirección de retorno.

Page 7: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 7

Para transferir el control a la función y respaldar la dirección de retorno, MIPS incluye la

instrucción:

JAL Label # Jump and Link

La instrucción realiza el salto a la etiqueta y de manera simultánea respalda en el registro

$ra el valor del contador de programa previamente incrementado ($ra = PC + 4).

Una función es aislada cuando no invoca a otras funciones, en esos casos no requiere

recursos de almacenamiento local y puede usar sólo registros temporales.

Ejercicio: Función aislada.

Considere la secuencia de código que incluye una función aislada:

… a = 10; b = 30; c = suma(a + b); …

int suma( int x, int y) { int aux; aux = x + y; return aux; }

¿Cómo se traduce a código MIPS? Asociando las variables a, b y c con los registros $s0,

$s1 y $s2.

Los registros $s0 a $s7 son seguros porque su valor debe conservarse a través de llamadas a

funciones. Una función que no es aislada (invoca a otras funciones) debe respaldar los

registros que utilice así como la dirección de retorno.

El espacio de almacenamiento temporal es la pila y se alojada en memoria principal. El

registro $sp es el apuntador de la pila. La pila crece de las direcciones altas a las

direcciones bajas, de manera que restando un valor constante al registro $sp se hace espacio

a la pila para respaldar los registros seguros, la dirección de retorno y disponer de un

espacio para datos locales complejos como los arreglos.

Ejercicio: Función recursiva.

Considere la función recursiva que obtiene el factorial de un número y con el uso de la

pseudo-instrucción mul $t0, $t1, $t2, traduzca a código MIPS.

Page 8: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 8

int fact ( int n ) {

if( n < 2) return 1; return n * fact(n – 1);

}

El registro apuntador de marco ($fp) tiene una función similar al apuntador de pila ($sp)

pero trabaja al nivel de funciones y no al nivel de datos, permitiendo restaurar al $sp ante

salidas abruptas de una función. El compilador determina si lo usa o no.

2.1.6 Manejo de Cadenas

Una cadena es una secuencia de caracteres. La mayoría de computadoras utilizan 8 bits

para representar un carácter de acuerdo al código ASCII (American Standar Code for

Information Interchange).

Un entero en MIPS utiliza 32 bits, que corresponde con el tamaño de los registros, sin

embargo, utilizar 32 bits por carácter sería un desperdicio de memoria.

MIPS incluye instrucciones para cargar y almacenar bytes:

• La instrucción LB (load byte) carga un byte desde la memoria colocándolo en los 8 bits

más a la derecha de un registro.

• La instrucción SB (store byte) toma un byte de los 8 bits más a la derecha de un registro

y los coloca en la memoria.

El formato para LB y SB es similar que el empleado para LW y SW.

LB $t0, cte ($t1) # $t0 = Mem[$t1 + cte] SB $t0, cte ($t1) # Mem[$t1 + cte] = $t0

LB y SB se distinguen de LW y SW porque no realizan un acceso a datos alineados en

memoria (la dirección efectiva de acceso no debe ser múltiplo de 4).

Ejercicio: Compilando una función para cadenas.

Traduzca a código MIPS el procedimiento strcpy, el cual copia una cadena y, terminada con

null, en una cadena x:

void strcpy ( char x[ ], char y[ ]) { int i = 0;

Page 9: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 9

while( ( x[i] = y[i] ) != 0 ) /* copia y compara */

i = i + 1; }

Tarea:

1. Con el ensamblador MIPS, indique la secuencia de instrucciones que evalúe a los

registros $s0, $s1 y $s2 y deje el valor del menor en $s3.

2. El siguiente código acumula los valores del arreglo A en la variable x:

for ( x = 0, i = 0; i < 10; i++ ) x = x + A[i];

¿Cuál es el código MIPS para este código? Suponga que el comienzo del arreglo A esta

en el registro $s3, que la variable x se asocia con $s1 y la variable i con $s2.

3. Transforme la siguiente asignación: c = ( a > b ) ? a : b; a código MIPS.

Asocie a, b y c con $s0, $s1 y $s2, respectivamente.

4. Realice una función en C que devuelva el mayor de un arreglo de n elementos y

posteriormente tradúzcala a código MIPS, respetando las convenciones establecidas

para la asociación de registros con variables.

5. Desarrolle el procedimiento bfind, en lenguaje ensamblador MIPS, que reciba como

argumento un apuntador a una cadena terminada con NULL (correspondería a $a0) y

localice la primer letra b en la cadena (se regresaría en $v0).

Si no hay b’s en la cadena, entonces bfind deberá regresar un apuntador al carácter

nulo (localizado al final de la cadena). Por ejemplo, si bfind recibe como argumento

un apuntador a la cadena “embebido” deberá devolver un apuntador al tercer carácter en

la cadena.

6. Escriba un procedimiento bcount, en lenguaje ensamblador MIPS, que reciba como

argumento un apuntador a una cadena terminada con NULL (correspondería a $a0) y

devuelva el número de b’s que aparecen en la cadena (en el registro $v0). Para la

implementación de bcount deberá utilizar la función bfind desarrollada en el

ejercicio anterior.

7. Escribir un procedimiento en código MIPS para calcular el n-ésimo término de la serie

de Fibonacci (F(n)), donde:

F(0) = 0 F(1) = 1 F(n) = F(n – 1) + F(n – 2) Si n > 1

Page 10: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 10

2.2 Tipos de instrucciones

Si se comparan las instrucciones aritméticas con las de acceso a memoria, se notará que

ambos tipos tiene tres operandos.

• Aritméticas: Los tres operandos son registros, con 5 bits es suficiente para definir un

registro.

• Acceso a memoria: Dos operandos son registros y el tercero es una constante, no es

conveniente disponer sólo de 5 bits para la constante, su valor sería muy limitado.

Si se quiere conservar el formato para los dos tipos de instrucciones, éstas van a tener

diferentes tamaños. La otra opción es conservar el tamaño, generando con ello diferentes

formatos de instrucciones.

Los diseñadores de MIPS optaron por la segunda opción y para mantener una arquitectura

regular, todas las instrucciones son de 32 bits, compatible con el tamaño de los datos

(principio 4).

En MIPS se tienen tres tipos de instrucciones: Tipo-R (por el uso de registros), Tipo-I (que

emplean una constante) y Tipo-J (destinadas a los saltos).

El formato para las instrucciones Tipo-R es:

6 bits 5 bits 5 bits 5 bits 5 bits 6 bits

OP RS RT RD shamt FUNCT

El significado para cada uno de los campos es:

• OP: Opcode, define el tipo de operación.

• RS: El primer operando fuente.

• RT: El segundo operando fuente.

• RD: El registro destino, obtiene el resultado de la operación.

• shamt: Cantidad de desplazamiento (shift amount), para instrucciones de

desplazamiento.

• FUNCT: Función, selecciona una variante de la operación, las operaciones aritméticas

tienen el mismo opcode pero se distinguen por este campo.

El formato para las instrucciones Tipo-I es:

6 bits 5 bits 5 bits 16 bits

OP RS RT Inmediato

El significado para cada uno de los campos es:

• OP: Opcode, define el tipo de operación.

Page 11: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 11

• RS: El primer operando fuente.

• RT: El segundo operando fuente.

• Inmediato: Constante requerida por la instrucción.

El formato para las instrucciones Tipo-J es:

6 bits 26 bits

OP Dirección

El significado para cada uno de los campos es:

• OP: Opcode, define el tipo de operación.

• Dirección: Destino del salto.

Organización de las instrucciones por su tipo:

Tipo – R Tipo – I Tipo – J

Instrucción Opcode Función Instrucción Opcode Instrucción Opcode

ADD SUB AND OR XOR NOR SLT JR SLL SRL

0 0 0 0 0 0 0 0 0 0

32 34 36 37 38 39 42 8 0 2

LW SW BEQ BNE ADDI ANDI ORI SLTI LUI LB SB

35 43 4 5 8 12 13 10 15 36 40

J JAL

2 3

Organización de las instrucciones por su función:

Aritméticas Lógicas Transferencia

de datos

Brincos

condicionales

Saltos

incondicionales

ADD SUB ADDI

AND OR XOR NOR SLL SRL ANDI ORI

LW SW LB SB LUI

SLT SLTI BEQ BNE

JR J JAL

2.3 Modos de direccionamiento

Los modos de direccionamiento determinan la forma en que las instrucciones tienen acceso

a sus operandos, en MIPS se tienen 5 modos de direccionamiento.

Page 12: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 12

1. Direccionamiento por registro: Los 3 operandos son registros, dos fuentes y un

destino.

Ejemplos de instrucciones que usan este modo de direccionamiento: add, sub, slt, etc.

2. Direccionamiento base con desplazamiento: Uno de los operandos está en una

localidad de memoria cuya dirección es la suma de un registro base y una constante que

forma parte de la misma instrucción.

Ejemplos de instrucciones que usan este modo de direccionamiento: lw, sw, etc.

3. Direccionamiento inmediato: Uno de los operandos es una constante y es parte de la

instrucción.

Ejemplos de instrucciones que usan este modo de direccionamiento: addi, slti, etc.

4. Direccionamiento relativo al PC: La dirección para un brinco condicional se forma

sumando el registro PC (Program Counter) con una constante que está en la instrucción.

Ejemplos de instrucciones que usan este modo de direccionamiento: beq y bne.

Page 13: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 13

5. Direccionamiento pseudo-directo: La dirección destino de un salto corresponde a la

concatenación de 26 bits que están en la misma instrucción con los bits más significativos

del PC.

Ejemplos de instrucciones que usan este modo de direccionamiento: j y jal.

2.4 Lenguaje máquina

Las instrucciones dentro de la memoria son almacenadas como secuencias de 1’s y 0’s,

para ello, básicamente se debe considerar el tipo de instrucción y los operandos, por

ejemplo, para la siguiente sentencia en alto nivel:

A[12] = h + A[8];

Suponiendo que el registro $s0 tiene el inicio del arreglo A y la variable h se asocia con

$s1, produce el siguiente código ensamblador:

LW $t0, 32($s0) # $t0 = A[8] (Tipo-I) ADD $t0, $s1, $t0 # $t0 = h + A[8] (Tipo-R) SW $t0, 48($s0) # A[12]= h + A[8] (Tipo-I)

Tomando en cuenta la distribución de los campos para cada tipo de instrucción,

corresponde con el código máquina siguiente (en decimal):

35 16 8 32

0 17 8 8 0 32

43 16 8 48

El código máquina en binario es (considerando el tamaño de cada campo):

100011 10000 01000 0000 0000 0010 0000

000000 10001 01000 01000 00000 100000

101011 10000 01000 0000 0000 0011 0000

Las instrucciones BEQ y BNE son relativas al PC, es decir, la dirección destino de un

brinco se obtiene sumando una constante con el PC previamente incrementado.

Page 14: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 14

En ensamblador se emplean etiquetas que posteriormente serán traducidas a números, los

números emplean una notación en complemento-2 para poder representar saltos hacía

adelante o hacia atrás. Así, para el siguiente código:

Loop: ... # Instrucción 1 ... # Instrucción 2

... # Instrucción 3 BEQ $t0, $t1, exit # 4 instrucciones adelante ... # Instrucción 4 ... # Instrucción 5 ... # Instrucción 6 BNE $t1, $t2, Loop # 9 instrucciones atrás Exit:

El código máquina, en decimal, para la instrucción BEQ es:

4 16 17 4

Mientras que para la instrucción BNE:

5 17 18 -9

Para ambas instrucciones, en binario, se tiene el siguiente código máquina:

BEQ 000100 10000 10001 0000 0000 0000 0100 BNE 000101 10001 10010 1111 1111 1111 0111

Las instrucciones J y JAL realizan saltos pseudo-directos, esto es, la instrucción incluye un

campo de 26 bits con la dirección de la instrucción, estos bits hacen referencia al número de

instrucciones dentro de un segmento de código y no al número de bytes.

Por hardware se realiza la multiplicación por 4 para obtener la dirección de byte y con el

resultado se remplaza a los 28 bits menos significativos del PC.

El registro PC conserva sus 4 bits más significativos, esto significa que el espacio total de

direccionamiento (4 Gbytes) es dividido en 16 páginas (de 256 MBytes).

Por ello, para generar el código máquina de las instrucciones J y JAL, se debe conocer la

dirección de la instrucción. Por ejemplo, si se considera la instrucción:

Dirección (decimal): Instrucción: 100 J Exit ... . . . 115 Exit: . . .

Page 15: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 15

El código máquina, en decimal, para la instrucción J es:

2 115

En binario se tiene:

000010 00 0000 0000 0000 0111 0011

Tarea:

1. Considerando el código MIPS generado para la secuencia de instrucciones que evalúa

los registros $s0, $s1 y $s2 y deja el valor del menor en $s3, traduzca a código máquina

asumiendo que el código inicia en la dirección 100 (en decimal).

2. Para el código MIPS que acumula los valores de un arreglo A en una variable x:

for ( x = 0, i = 0; i < 10; i++ ) x = x + A[i];

Escriba el código máquina que corresponde, nuevamente asuma que la dirección inicial

para la secuencia de código es la 100 (en decimal).

2.5 Programas de ejemplo

Cuando se traduce de un lenguaje de alto nivel a ensamblador, en general, se realizan los

pasos siguientes:

a) Se asocian los registros con las variables del programa.

b) Se produce el código para el cuerpo de la función.

c) Se respaldan los registros a conservar en la función.

2.5.1 La función SWAP

La función swap intercambia dos localidades de memoria. El código C de la función es:

void swap ( int v[ ], int k ) { int temp;

temp = v[k]; v[k] = v[k+1]; v[k+1] = temp;

}

a) Asociación de registros con variables. La función swap recibe sus argumentos en los

registros $a0 (arreglo v) y $a1 (variable k).

Puesto que swap es una función aislada, para la variable temp se utiliza el registro $t0.

Page 16: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 16

b) El cuerpo de la función. Para el traducir el cuerpo de la función se debe tener en cuenta

que los datos se constituyen de palabras de 4 bytes, de manera que para obtener la dirección

de v[k] primero se debe multiplicar a k por 4.

SLL $t1, $a1, 2 # $t1 = 4*k ADD $t1, $a0, $t1 # $t1 tiene la dirección de v[k]

Ahora es posible hacer la carga de v[k] y de v[k + 1]

LW $t0, 0($t1) # reg $t0 (temp) = v[k] LW $t2, 4($t1) # reg $t2 = v[k + 1]

Finalmente se hace el almacenamiento en memoria.

SW $t2, 0($t1) # v[k] = reg $t2 SW $t0, 4($t1) # v[k + 1] = reg $t0 (temp)

c) Respaldo de registros. Esta función es aislada, por lo que no requiere respaldar

información en la pila.

El código completo para la función swap es:

Cuerpo del procedimiento SWAP:

SLL $t1, $a1, 2 # $t1 = 4*k ADD $t1, $a0, $t1 # $t1 tiene la dirección de v[k] LW $t0, 0($t1) # reg $t0 (temp) = v[k] LW $t2, 4($t1) # reg $t2 = v[k + 1] SW $t2, 0($t1) # v[k] = reg $t2 SW $t0, 4($t1) # v[k + 1] = reg $t0 (temp)

Retorno del procedimiento JR $ra # Regresa a la función invocadora

2.5.2 La función SORT

La función sort ordena los elementos de un arreglo, su código C es:

void sort ( int v[ ], int n ) { int i, j;

for ( i = 0; i < n; i++ ) for (j = i – 1; j >= 0 && v[j] > v[j + 1]; j--)

swap( v, j);

}

Page 17: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 17

a) Asociación de registros con variables. Los dos argumentos se reciben en los registros $a0

(inicio del arreglo v) y $a1 (la variable n). La variable i se asocia con el registro $s0 y j con

el registro $s1 (registros seguros porque no es una función aislada).

b) El cuerpo de la función. Para el ciclo más externo:

for ( i = 0; i < n; i++ )

La inicialización y comparación:

ADD $s0, $zero, $zero # i = 0 for1: SLT $t0, $s0, $a1 # $t0 = 1 si i < n

BEQ $t0, $zero, exit1 # Si $t0 = 0, termina

Continuaría con el cuerpo del for, para que posteriormente se realice el incremento:

ADDI $s0, $s0, 1 # i ++ J for1o # Siguiente iteración

El segundo for en C es:

for (j = i – 1; j >= 0 && v[j] > v[j + 1]; j--)

La inicialización de la variable j corresponde a:

ADDI $s1, $s0, -1 # j = i - 1

Este ciclo prueba dos expresiones ligadas con un operador AND, si la primera falla, es

suficiente para terminar con el ciclo. El cuerpo del for se realiza solo cuando las dos

expresiones son verdaderas. La comparación del ciclo es:

for2o: SLT $t0, $s1, $zero # $t0 = 1 si j < 0 BNE $t0, $zero, exit2 # Termina si $t0 = 1 SLL $t1, $s1, 2 # $t1 = 4*j ADD $t2, $a0, $t1 # $t2 = &(v[j]) LW $t3, 0($t2) # $t3 = v[j] LW $t4, 4($t2) # $t4 = v[j + 1] SLT $t0, $t4, $t3 # $t0 = 1 si $t4 < $t3 BEQ $t0, $zero, exit2 # Si $t0 = 0, termina

Después del cuerpo del ciclo se culmina con el decremento de j y el paso a la siguiente

iteración:

ADDI $s1, $s1, -1 # j— J for2o # Siguiente iteración

Page 18: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 18

El cuerpo del ciclo for interno incluye la llamada a la función swap, para ello

primeramente deben revisarse los argumentos.

El primer argumento de sort coincide con el primer argumento de swap. El segundo

argumento cambia, éste debe respaldarse en un registro seguro:

ADD $s2, $a1, $zero # Respalda n en $s2 ADD $a1, $s1, $zero # $a1 = j, 2º argumento JAL SWAP ADD $a1, $s2, $zero # Recuperación de n

Es conveniente realizar el respaldo de argumentos en registros seguros al inicio de la

función y emplear los registros seguros en el cuerpo de la misma.

Esto hace posible la modificación de los registros de los argumentos cada vez que sea

necesario y no se deben recuperar después de la llamada.

c) Respaldo de registros. Además de los tres registros seguros empleados ($s0, $s1 y $s2)

debe respaldarse la dirección de retorno, para que sort regrese adecuadamente y el

retorno no se vea afectado por el llamado a swap.

El prólogo de la función sort es:

ADDI $sp, $sp, -16 # Hace espacio para 4 registros SW $ra, 12( $sp ) # Salva a $ra en la pila SW $s2, 8( $sp ) # Salva a $s2 en la pila SW $s1, 4( $sp ) # Salva a $s1 en la pila SW $s0, 0( $sp ) # Salva a $s0 en la pila

Al final de la función se debe hacer la recuperación de registros, antes de regresar a la

función invocadora.

El código completo para la función sort es:

Respaldo de registros SORT: ADDI $sp, $sp, -16 # Hace espacio para 4 registros

SW $ra, 12( $sp ) # Salva a $ra en la pila SW $s2, 8( $sp ) # Salva a $s2 en la pila SW $s1, 4( $sp ) # Salva a $s1 en la pila SW $s0, 0( $sp ) # Salva a $s0 en la pila ADD $s2, $a1, $zero # Respalda n en $s2

Inicio del ciclo for externo ADD $s0, $zero, $zero # i = 0

Page 19: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 19

for1: SLT $t0, $s0, $a1 # $t0 = 1 si i < n BEQ $t0, $zero, Exit1 # Si $t0 = 0, termina

Cuerpo del for externo, inicio del for interno ADDI $s1, $s0, -1 # j = i - 1

for2o: SLT $t0, $s1, $zero # $t0 = 1 si j < 0 BNE $t0, $zero, Exit2 # Termina si $t0 = 1 SLL $t1, $s1, 2 # $t1 = 4*j ADD $t2, $a0, $t1 # $t2 = &(v[j]) LW $t3, 0($t2) # $t3 = v[j] LW $t4, 4($t2) # $t4 = v[j + 1] SLT $t0, $t4, $t3 # $t0 = 1 si $t4 < $t3 BEQ $t0, $zero, exit2 # Si $t0 = 0, termina

Cuerpo del for interno ADD $a1, $s1, $zero # $a1 = j, 2º argumento JAL SWAP

Cierre del for interno ADDI $s1, $s1, -1 # j— J for2o # Siguiente iteración

Cierre del for externo Exit2: ADDI $s0, $s0, 1 # i ++

J for1o # Siguiente iteración

Recuperación de registros LW $ra, 12( $sp ) # Recupera $ra de la pila LW $s2, 8( $sp ) # Recupera $s2 de la pila LW $s1, 4( $sp ) # Recupera $s1 de la pila LW $s0, 0( $sp ) # Recupera $s0 de la pila ADDI $sp, $sp, 16 # Restablece al registro $SP

2.5.2 Arreglos vs Apuntadores

A pesar de que los arreglos y apuntadores comparten algunas características y es posible

pasar un arreglo a una función que espera un apuntador o vice-versa, los compiladores

traducen de manera diferente un programa con arreglos que otro con apuntadores.

Estas diferencias se reflejan al traducir la función clear, encargada de colocar 0’s a todos

los elementos de un arreglo:

Versión con un arreglo Versión con un apuntador void clear1(int array[], int size) { int i; for( i = 0; i < size; i++) array[i] = 0; }

void clear2(int *array, int size) { int *p; for(p=&array[0];p<&array[size]; p++) *p = 0; }

Page 20: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 20

El código MIPS de ambas versiones:

Versión con un arreglo Versión con un apuntador clear1: add $t0, $zero, $zero for1: slt $t1, $t0, $a1 beq $t1, $zero, fin_for1 sll $t2, $t0, 2 add $t2, $t2, $a0 sw $zero, 0($t2) addi $t0, $t0, 1 j for1 fin_for1: jr $ra

clear2: add $t0, $a0, $zero sll $t1, $a1, 2 add $t1, $t1, $a0 for2: slt $t2, $t0, $t1 beq $t2, $zero, fin_for2 sw $zero, 0($t0) addi $t0, $t0, 4 j for2 fin_for2: jr $ra

El código de la versión con apuntadores es más rápido porque incluye menos instrucciones

en la parte repetitiva. En general, los compiladores capaces de optimizar código intentan

manejar los arreglos sumando una variable para obtener la dirección del i-ésimo elemento,

en lugar de realizar multiplicaciones. El código resultante será más rápido porque para toda

arquitectura, una suma es más rápida que una multiplicación.

2.5.3 Un simulador para el repertorio de instrucciones

El simulador QtSpim fue creado por el Dr. James Larus en la Universidad de Wisconsin,

Madison. El Dr. Larus actualmente es investigador de la empresa Microsoft.

QtSpim es un simulador para programas escritos en lenguaje ensamblador para los

procesadores R2000/R3000, los cuales son procesadores de 32 bits de la compañía MIPS.

QtSpim proporciona un depurador simple y un juego simple de servicios del sistema

operativo.

El programa se puede descargar del sitio:

https://sourceforge.net/projects/spimsimulator/

El simulador incluye un kernel que inicializa al simulador y una consola para interacción

con el usuario. El kernel realiza un salto a la etiqueta main, por lo que debe incluirse en el

programa a simular. El acceso a la consola se realiza mediante servicios del sistema

(SYSCALL), permitiendo al usuario introducir información y leer resultado.

El número de servicio se coloca en el registro $v0 y sus argumentos en $a0 o $f12,

dependiendo de si es entero o flotante, de manera similar, el resultado es dejado en $v0 o

$f0.

Page 21: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 21

En la siguiente tabla se muestran los diferentes servicios del programa.

Servicio Número Argumentos Resultados

print_int 1 $a0 = integer print_float 2 $f12 = float print_double 3 $f12 = doublé print_string 4 $a0 = string

read_int 5 integer (in $v0) read _float 6 float (in $f0) read _double 7 double (in $f0) read _string 8 $a0 = buffer, $a1 = length

sbrk 9 $a0 = amount Address (in $v0) exit 10

Pseudo-instrucciones:

Son instrucciones que el simulador reconoce pero no tienen una interpretación directa en

hardware, sino que deben traducirse a una o más instrucciones reales para que puedan ser

ejecutadas.

Las pseudo-instrucciones dan flexibilidad a los programadores, algunos ejemplos:

Pseudo-instrucción Instrucción o instrucciones reales move $t1, $t0 ori $t1, $zero, $t0 mul $s1, $s2, $s3 mult $s2, $s3 (resultado en HI y LO)

mflo $s1 (mueve el reg. LO a $s1) (mfhi es para mover el reg. HI)

mul $t4, $t1, 4 ori $1, $0, 4 mult $9, $1 mflo $12

la $a0, str1 lui $a0, HIGH(str1) << 16 ori $a0, LOW(str1)

Ejemplos en el uso del simulador:

1. Programa “Hola Mundo”. El programa muestra cómo se usa el servicio 4 para enviar

una cadena a la consola.

main: addi $v0, $zero, 4 # Servicio 4 la $a0, cadena # Ubica el argumento syscall # Solicita el servicio jr $31 .data

cadena: .asciiz "Hola Mundo"

Page 22: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 22

2. Suma de dos números. Programa para mostrar el uso de los servicios 5 y 1 (lee un

entero y escribe un entero).

main: addi $v0, $zero, 4 la $a0, str1 syscall # Pide un número addi $v0, $0, 5 syscall # Lee el número add $t0, $0, $v0 # se coloca en $t0 addi $v0, $zero, 4 la $a0, str2 syscall # Pide otro número addi $v0, $0, 5 syscall # Lee el otro numero add $t1, $0, $v0 # se coloca en $t1 addi $v0, $zero, 4 la $a0, str3 syscall # Mensaje para dar el resultado add $a0, $t0, $t1 addi $v0, $zero, 1 syscall # Muestra el resultado addi $v0, $zero, 4 la $a0, str4 syscall # Mensaje final jr $ra # fin del main .data

str1: .asciiz "Dame un numero: " str2: .asciiz "Dame otro numero: " str3: .asciiz "La suma de los numeros es : " str4: .asciiz "\n\nFin del programa. . ."

3. Llamada a una función. Desde el main se invocará a la función factorial. El

main ya no es una función aislada, por lo que debe emplear registros seguros. No se

incluye el código de la función factorial.

main: addi $sp, $sp, -12 # Respaldos en la Pila sw $ra, 0 ($sp) sw $s0, 4 ($sp) sw $s1, 8 ($sp) addi $v0, $zero, 4 la $a0, str1 syscall # Pide un número addi $v0, $0, 5 syscall # Lee el número

Page 23: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 23

add $s0, $0, $v0 # se coloca en $s0 add $a0, $s0, $zero jal factorial # Llamada a factorial add $s1, $v0, $zero addi $v0, $zero, 4 la $a0, str2 syscall # Mensaje para dar el resultado add $a0, $s0, $zero addi $v0, $zero, 1 syscall # El numero addi $v0, $zero, 4 la $a0, str3 syscall add $a0, $s1, $zero addi $v0, $zero, 1 syscall # Su factorial

addi $v0, $zero, 4 la $a0, str4 syscall # Mensaje final lw $ra, 0 ($sp) # Recuperacion de la Pila lw $s0, 4 ($sp) lw $s1, 8 ($sp) addi $sp, $sp, 12 jr $ra # fin del main

factorial: . . . # El código desarrollado . . . # en ejercicios anteriores jr $ra

.data

str1: .asciiz "Dame un numero: " str2: .asciiz "El factorial del numero " str3: .asciiz " es : " str4: .asciiz "\n\nFin del programa. . ."

4. Manejo de un arreglo. La pila es el espacio en donde se puede colocar un arreglo para

su posterior manipulación. En este ejemplo se muestra cómo solicitar espacio, cómo

tener acceso y cómo liberarlo.

El código C pide los datos de un arreglo y los imprime en orden inverso:

Page 24: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 24

void main(){ int i, n, *A, *t;

printf("Manejo de un arreglo\n"); printf("Indica el tamaño del arreglo: "); scanf("%d", &n); A = (int *) malloc(n*sizeof(int));

for( t = A, i = 0; i < n; i++, t++) {

printf(" Dame el dato %d : ", i); scanf("%d", t);

}

printf("\nLos números en orden inverso: \n");

for( t = &A[n-1], i = 0; i < n; i++, t--) printf(" %d\n", *t);

free(A); }

El código MIPS, considerando que es una función aislada, es:

main: addi $v0, $zero, 4 la $a0, str1 syscall # Primer mensaje addi $v0, $zero, 4 la $a0, str2 syscall # Pide el tamaño addi $v0, $0, 5 syscall # Lee el tamaño add $t1, $0, $v0 # se coloca en $t1 # Reserva el espacio en memoria sll $t4, $t1, 2 # Total de bytes sub $sp, $sp, $t4 # Espacio en la pila addi $t2, $sp, 0 # $t2 = &A[0]

# Inicia el primer for:

addi $t0, $0, 0 # i = 0 addi $t3, $t2, 0 # t = A

for1: slt $t5, $t0, $t1 beq $t5, $zero, fin_for1 li $v0, 4 la $a0, str3 syscall # Pide el numero li $v0, 1 add $a0, $0, $t0

Page 25: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 25

syscall # Imprime el índice li $v0, 4 la $a0, str4 syscall # dos puntos li $v0, 5 syscall # Lee el número sw $v0, 0($t3) # Almancena addi $t0, $t0, 1 # i ++ addi $t3, $t3, 4 # t ++ j for1

fin_for1: li $v0, 4 la $a0, str5 syscall # Mensaje de notificación

# Inicia el segundo for

addi $t0, $0, 0 # i = 0 addi $t4, $t1, -1 # $t4 = n - 1 sll $t4, $t4, 2 # $t4 = 4 * (n - 1) add $t3, $t2, $t4 # t = &A[n-1]

for2: slt $t5, $t0, $t1 beq $t5, $zero, fin_for2 lw $t6, 0($t3) # Obtiene el número li $v0, 1 add $a0, $0, $t6 syscall # lo imprime li $v0, 4 la $a0, str6 syscall #imprime el retorno de carro addi $t0, $t0, 1 #i ++ addi $t3, $t3, -4 #t -- j for2

fin_for2: sll $t4, $t1, 2 # Total de bytes add $sp, $sp, $t4 # Libera espacio jr $ra # Termina

#Cadenas del programa .data

str1: .asciiz " Manejo de un arreglo \n" str2: .asciiz "Indica el tamaño del arreglo : " str3: .asciiz "Dame el número " str4: .asciiz " : " str5: .asciiz "\nLos numeros en orden inverso son: \n " str6: .asciiz "\n "

Page 26: Arquitectura del repertorio de instruccionesfsantiag/ArqElectronica/2a_Unidad_2020A.pdf · Las operaciones relacionales más complejas se consiguen combinando estás instrucciones

Arquitectura de Computadoras 2. Arquitectura del repertorio de instrucciones

Santiago E. Felipe/UTM-2019 26

Tarea:

Los siguientes ejercicios permitirán evaluar al simulador:

1. Realice un programa que solicite 3 números e indique cual es el menor de ellos.

2. Realice la función principal para el programa SORT y simúlelo, recordar que debe

incluirse a la función SWAP, el número de elementos deberá ser solicitado al usuario

(sug. Puede usarse la pila para almacenar el arreglo).

3. Realice un programa que obtenga el menor y el mayor de un arreglo de n elementos

proporcionados por el usuario (sug. Acondicione la función desarrollada en la tarea

anterior).

4. Realice un programa recursivo que obtenga al n-ésimo término de la serie de Fibonacci.

Reutilice la función desarrollada en una tarea previa.