AC - Practica 1 Resuelta PDF

Title AC - Practica 1 Resuelta
Author Fernando Hidalgo
Course Arquitectura de Computadores
Institution Universidad de Sevilla
Pages 22
File Size 1.3 MB
File Type PDF
Total Downloads 33
Total Views 158

Summary

Arquitectura de computadores, Código C, Lenguaje Máquina, Binario, Algortimos, Ensamblador, SnapDragon, Código Fuente...


Description

Arquitectura de Computadores 2º curso del Grado en Ingeniería Informática – Ingeniería del Software Departamento de Arquitectura y Tecnología de Computadores. Universidad de Sevilla Boletín para las sesiones de Laboratorio Práctica 1: "REPERTORIO DE INSTRUCCIONES RISC: PROCESADOR MIPS" OBJETIVOS En esta práctica se estudia el repertorio de instrucciones y la programación a bajo nivel (lenguaje ensamblador) de un procesador real de tipo RISC (el procesador MIPS). Para ello, utilizaremos el simulador MARS (de libre distribución bajo licencia MIT) que puede descargarse de la siguiente dirección: http://courses.missouristate.edu/KenVollmar/MARS/index.htm Con esta práctica se pretende que el alumno: • • • • • •

Consolide sus conocimientos sobre procesadores RISC. Se familiarice con la arquitectura y juego de instrucciones del procesador MIPS. Sea capaz de utilizar un entorno de desarrollo para programar un procesador a bajo nivel. Comprenda los detalles de la ejecución del código en un procesador RISC. Adquiera habilidades de programación a bajo nivel de un procesador de tipo RISC. Conozca cómo se traducen a bajo nivel las estructuras típicas de un lenguaje de programación de alto nivel.

Es importante conocer la programación a bajo nivel (lenguaje ensamblador), ya que cualquier programa escrito en cualquier lenguaje de programación de alto nivel es traducido a lenguaje máquina (bajo nivel) por el compilador y éste es el código que realmente se ejecuta. El conocimiento de cómo se traducen las estructuras de los lenguajes de alto nivel puede ayudar, por ejemplo, a hacer que el código sea más eficiente. INTRODUCCIÓN A LA ARQUITECTURA MIPS32 El procesador MIPS R2000 es un procesador RISC de 32 bits desarrollado en 1986 que implementa la arquitectura MIPS32. Este procesador es un claro ejemplo de arquitectura RISC de 32 bits, y está compuesto por una CPU y dos coprocesadores auxiliares:

1

Registros: •

Dentro de la CPU disponemos de 32 registros de propósito general de 32 bits cada uno, numerados del 0 al 31.



El registro 0 está cableado por hardware (hardwired) a 0.



Aunque la CPU no impone ninguna restricción sobre el uso de estos registros (es decir, se pueden utilizar para cualquier propósito), existe una convención de uso de que deben seguir todos los programas para el MIPS. Si el programador no respeta esta convención, el programa resultante podría no funcionar correctamente cuando interactúe con el resto del sistema (por ejemplo, si se realizan llamadas a funciones de una biblioteca de funciones estándar). La siguiente tabla muestra el nombre del registro en el código ensamblador, el número de registro correspondiente dentro de la CPU y el uso establecido por la convención de uso. Nombre



Número

Uso

zero

0

Valor constante 0

at

1

Reservado para el ensamblador

v0, v1

2, 3

Evaluación de expresiones y valor devuelto por las funciones

a0, …, a3

4, …, 7

Argumentos a rutina

t0, …, t7

8, …, 15

Temporales (no preservados a través de llamada1)

s0, …, s7

16, …, 23

Temporales (preservados a través de llamada2)

t8, t9

24, 25

Temporales (no preservados a través de llamada)

k0, k1

26, 27

Reservados para el kernel del Sistema Operativo

gp

28

Puntero global

sp

29

Puntero de pila (stack pointer)

fp

30

Puntero de marco (frame pointer)

ra

31

Dirección de retorno (para retorno de procedimientos)

También existen otros 2 registros especiales, denominado hi y lo (alto y bajo, respectivamente), que se usan para operaciones de multiplicación y división de números enteros. Estos registros no tienen numeración y solo pueden usarse con algunas instrucciones específicas para su manipulación.

Memoria:



El acceso a memoria se realiza mediante direcciones de 32 bits. Por consiguiente, las direcciones de memoria van de 0 a 232-1 (0xffffffff)



El acceso puede realizarse a nivel de byte (8 bits), media palabra (16 bits) y palabra (32 bits).



Los accesos a palabra serán siempre a direcciones múltiplos de 4. Los accesos a media palabra serán a direcciones múltiplos de 2.



El MIPS R2000 puede ser configurado en el arranque para que utilice el ordenamiento Big-Endian o Little-Endian. Sin embargo, el simulador MARS que utilizaremos en prácticas sólo utiliza el ordenamiento Little-Endian.

Modos de direccionamiento: El modo de direccionamiento es la forma en la que se especifica dónde se encuentran cada operando de la instrucción. •

Inmediato. • • • •

1 2

El operando se encuentra en la propia instrucción (16 bits). Solo se permite para operandos fuente. Según la instrucción, se producirá una extensión de signo o extensión con ceros (ver MIPS Reference Data Card). Notación: valor

Cuando llamamos a una función, dicha función puede modificar el valor de los registros temporales t0 a t9 Cuando llamamos a una función, la convención de uso establece que la función llamada no modificará el valor de los registros s0 a s7. Es decir, el valor de dichos registros después de la llamada a la función serán los mismos que tenían antes de la llamada.

2



• Ejemplo: add $t7, $s2, -4 → t7 = s2 – 4 (extendiendo el signo) Directo a registro. • • • •



Indirecto a registro con desplazamiento. •

• • • •

El operando se encuentra almacenado en memoria, en una dirección relativa al valor de un registro. La dirección de memoria donde se encuentra el operando se calcula sumando el desplazamiento (un valor de 16 bits con signo) al valor del registro. Se permite para operandos fuente en operaciones de carga, y para operandos destino en operaciones de almacenamiento. Notación: valor($registro) Ejemplo: lw $s2, -40($t1) → s2 = dato almacenado en la dirección de memoria [t1 - 40]

Relativo al PC con desplazamiento. • •

• • •

El operando se encuentra almacenado en un registro. Se permite para operandos fuente o destino. Notación: $registro Ejemplo: add $s3, $s2, $s1 → s3 = s2 + s1

Se utiliza en instrucciones de salto condicional. La dirección destino del salto se obtiene sumando el desplazamiento (valor de 16 bits con signo) a la dirección de memoria de la instrucción siguiente (la instrucción siguiente se encuentra en la dirección PC+4). El desplazamiento está expresado en palabras por lo que es multiplicado por 4 para expresarlo en bytes (añadiendo dos bits 0 a la derecha). Notación: desplazamiento Ejemplo: beq $t4, $t7, 40 → Si t4 == t7, PC = PC+4 + 4*40, extendiendo el signo

Pseudo-directo. •

Se utiliza en instrucciones de salto incondicional.



La dirección destino del salto se obtiene concatenando los 4 bits más significativos de la dirección de memoria de la instrucción siguiente con la dirección especificada en la instrucción de salto (26 bits). La dirección está expresada en palabras por lo que se multiplica por 4 para expresarla en bytes (añadiendo dos bits 0 a la derecha). Notación: dirección Ejemplo: j 1500 → PC = bits 31 a 28 de (PC+4) concatenados con 1500*4

• •

3

Formatos de instrucciones Todas las instrucciones MIPS32 son de 32 bits de longitud (el mismo tamaño que el de una palabra). A los distintos campos de las instrucciones se les da un nombre para su rápida identificación. El nombre y significado de cada campo se muestra a continuación: • • • • • • • •

opcode (Cód. Op.): Es el código de la operación, o código de la instrucción. rs: Es el primer registro fuente (o registro base). rt: Es el segundo registro fuente (si bien en las instrucciones de tipo I son el registro destino). rd: Es el registro destino (donde se almacena el resultado de la operación). shamt: Tamaño del desplazamiento en bits (shift amount) en instrucciones de rotación y desplazamiento de bits. funct: Selecciona la variante específica de la operación indicada en el opcode. offset: Valor numérico de 16 bits. En operaciones con operandos inmediatos contiene el valor del operando. Contiene el desplazamiento en operaciones con operandos en memoria (direccionamiento Indirecto a registro con desplazamiento). target: Valor numérico de 26 bits que indica la dirección destino en saltos incondicionales.

4

MIPS presenta tres formatos básicos de instrucción:

Todas las instrucciones (de la CPU) MIPS32 responden a uno de estos tres formatos. Para ver el formato de cada instrucción, consultar el MIPS Reference Data Card. Clases de instrucciones Las diferentes instrucciones de la arquitectura MIPS32 permiten realizar operaciones de carga y almacenamiento, desde y hacia memoria respectivamente, operaciones aritméticas y lógicas con números enteros en la CPU, y con números en coma flotante en el coprocesador 1 (FPU), y operaciones de control del flujo de ejecución del programa, mediante comparaciones y saltos tanto condicionales como incondicionales. Las tablas que se muestran a continuación utilizan la siguiente nomenclatura para describir el funcionamiento de las instrucciones: •

## : Concatenación



(…)x : se repite x veces el valor (de un sólo bit) indicado por la expresión entre paréntesis



←x : indica transferencia de x bits



Xi..j : selecciona los bits de la expresión X que van desde el bit i hasta el bit j. El valor 0 indica el bit menos significativo mientras que el valor 31 el más significativo.



M[...]: valor de la memoria en la dirección indicada.

Instrucciones de transferencia y de carga / almacenamiento •

Las operaciones de carga (load) copian información desde la memoria a los registros.



Las operaciones de almacenamiento (store) copian información de los registros a la memoria.



Las operaciones de transferencia copian información entre los registros de propósito general y los registros hi y lo; o bien, cargan un valor inmediato en la parte alta de un registro.



Son instrucciones de tipo I. Ejemplo instrucción

Instrucción

Significado

lw $t1, 40($t3)

Carga palabra

t1 ←32 M[40+t3]31..0

lh $t1, 40($t3)

Carga media palabra

t1 ←32 (M[40+t3]15)16 ## M[40+t3]15..0

lhu $t1, 40($t3)

Carga media palabra sin signo

t1 ←32 016 ## M[40+t3]15..0

5

Ejemplo instrucción

Instrucción

Significado

lb $t1, 40($t3)

Carga byte

t1 ←32 (M[40+t3]7)24 ## M[40+t3]7..0

lbu $t1, 40($t3)

Carga byte sin signo

t1 ←32 024 ## M[40+t3]7..0

lui $s2, 0x0987

Carga inmediato superior

s2 ←32 0x0987 ## 016

sw $t4, 56($s6)

Almacena palabra

M[56+s6] ←32 t431..0

sh $t4, 56($s6)

Almacena media palabra

M[56+s6] ←16 t415..0

sb $t4, 56($s6)

Almacena byte

M[56+s6] ←8 t47..0

mfhi $t3

Copia desde hi

t3 ←32 hi

mflo $t3

Copia desde lo

t3 ←32 lo

mthi $t3

Copia hacia hi

hi ←32 t3

mtlo $t3

Copia hacia lo

lo ←32 t3

Instrucciones aritméticas y lógicas •

Todas las instrucciones aritméticas y lógicas necesitan que los operandos estén previamente almacenados en registros.



Para cada operación, existen versiones en las que intervienen 3 registros y versiones con 2 registros y un dato inmediato.



Son instrucciones de tipo R (3 registros) o tipo I (2 registros e inmediato).

Ejemplo instrucción

Instrucción

Significado

add $t1, $s1, $s3

Suma

t1 ←32 s1 + s3

sub $t1, $s1, $s3

Resta

t1 ←32 s1 - s3

mul $s6, $t4, $t0

Multiplica (32 bits)

s6 ←32 (t4 * t0)31..0

mult $t4, $t0

Multiplica (resultado de 64 bits)

hi ←32 (t4 * t0)63..32 lo ←32 (t4 * t0)31..0

div $t4, $t0

Divide

hi ← 32 t4 % t0 lo ←32 t4 / t0

madd $t4, $t0

Multiplica y suma

hi ←32 ((hi ## lo) + t4 * t0)63..32 lo ←32 ((hi ## lo) + t4 * t0)31..0

msub $t4, $t0

Multiplica y resta

hi ←32 ((hi ## lo) - t4 * t0)63..32 lo ←32 ((hi ## lo) - t4 * t0)31..0

or $t3, $s1, $t2

Or (bit a bit)

t3 ← 32 s1 or t2

and $t3, $s1, $t2

And (bit a bit)

t3 ← 32 s1 and t2

xor $t3, $s1, $t2

Xor (bit a bit)

t3 ← 32 s1 xor t2

nor $t3, $s1, $t2

Not Or (bit a bit)

t3 ← 32 not (s1 or t2)

sll $t3, $s1, 3

Desplazamiento lógico a izquierda

t3 ← 32 s128..0 ## 03

srl $t3, $s1, 3

Desplazamiento lógico a derecha

t3 ← 32 03 ## s131..3

slt $s0, $t1, $t2

Activa si es menor Si t1 < t2, entonces s0 = 1; en otro caso, (en el ejemplo, activa s0 si t1 es s0 = 0 menor que t2)

Otras instrucciones aritméticas usuales son: addi, addu, addiu (suma inmediato sin signo), subu, mulu, multu, divu, maddu, msubu. Otras instrucciones lógicas son: ori, andi, xori, slti, sltiu. Instrucciones de control de flujo •

Son instrucciones de tipo I (2 registros e inmediato) o de tipo J.

6

Ejemplo instrucción

Instrucción

Significado

j addr

Salta

PC ←32 (PC + 4)31..28 ## addr ## 02

jr $t3

Salta con registro

PC ←32 t3

jal addr

Salta a subrutina (salto y enlace)

ra ←32 PC + 8 PC ←32 (PC + 4)31..28 ## addr ## 02

jalr $t3

Salta a subrutina con registro (salto ra ←32 PC + 8 PC ←32 t3 y enlace con registro)

beq $s6, $t4, loop

Salta si igual

Si s6 == t4, entonces PC ←32 PC+4 + (loop15)14 ## loop ## 02

bne $s6, $t4, loop

Salta si distinto

Si s6 != t4, entonces PC ←32 PC+4 + (loop15)14 ## loop ## 02

bltz $s1, loop

Salta si menor que 0

Si s1 < 0, entonces PC ←32 PC+4 + (loop15)14 ## loop ## 02

blez $t1, loop

Salta si menor o igual que 0

Si t1 0, entonces PC ←32 PC+4 + (loop15)14 ## loop ## 02

bgez $t3, loop

Salta si mayor o igual que 0

Si t3 >= 0, entonces PC ←32 PC+4 + (loop15)14 ## loop ## 02

Pseudoinstrucciones Debido a que el repertorio de instrucciones del MIPS está diseñado para ser lo más reducido posible, existen operaciones básicas que no se pueden realizar con instrucciones específicas. Dichas operaciones deben traducirse a una secuencia de instrucciones o realizarse con instrucciones que, aparentemente, fueron diseñadas para un fin distinto. Para facilitar la tarea al programador, el ensamblador define una serie de pseudoinstrucciones que realizan dichas operaciones básicas. Las pseudoinstrucciones no forman parte del repertorio de instrucciones de la CPU; es decir, son instrucciones del lenguaje ensamblador que no están implementadas en hardware. El ensamblador MIPS transforma estas pseudoinstrucciones en instrucciones reales, usando si es necesario el registro at (reservado para el ensamblador, como vimos anteriormente), y convirtiéndolas en una o más instrucciones reales. Un ejemplo de pseudoinstrucción es la siguiente: move $t3, $t5

→ t3 = t5

que el ensamblador transformaría en: addu $t3, $zero, $t5

→ t3 = 0 + t5

Muchas de las instrucciones de salto condicional (salvo beq y bne) son también pseudoinstrucciones, en este caso el ensamblador usa el registro at. Por ejemplo, la pseudoinstrucción bgt $s2, $t4, loop

→ Salta a loop si s2 > t4

se transformaría en slt $at, $t4, $s2 bne $at, $zero, loop

Ejemplo pseudoinstrucción

→ Si t4 < s2, at = 1, en otro caso, at = 0 → Salta a loop si at != 0

Pseudoinstrucción

Traducción a instrucciones

Significado

blt $t1, $t2, loop

Salta si menor

slt $at, $t1, $t2 bne $at, $zero, loop

Si t1 < t2, PC ←32 PC+4 + (loop15)14 ## loop ## 02

bgt $t1, $t2, loop

Salta si mayor

slt $at, $t2, $t1 bne $at, $zero, loop

Si t1 > t2, PC ←32 PC+4 + (loop15)14 ## loop ## 02

7

Ejemplo pseudoinstrucción

Pseudoinstrucción

Traducción a instrucciones

Significado

ble $t1, $t2, loop

Salta si menor o igual slt $at, $t2, $t1 beq $at, $zero, loop

Si t1 < t2, PC ←32 PC+4 + (loop15)14 ## loop ## 02

bge $t1, $t2, loop

Salta si mayor o igual slt $at, $t1, $t2 beq $at, $zero, loop

Si t1 >= t2, PC ←32 PC+4 + (loop15)14 ## loop ## 02

li $t1, 5000

Carga inmediato de 16 bits con signo

addiu $t1, $zero, 0x1388

t1 ←32 016 ## 0x138815..0

li $t1, -5000

Carga inmediato de 16 bits con signo

addiu $t1, $zero, 0xec78

t1 ←32 116 ## 0xec7815..0

li $t1, 0xa0b0

Carga inmediato de 16 bits sin signo

ori $t1, $zero, 0xa0b0

t1 ←32 016 ## 0xa0b015..0

li $t1, 0xa0b0c0

Carga inmediato de 32 bits

lui $at, 0x00a0 ori $t1, $at, $b0c0

t1 ←32 0x00a0b0c031..0

la $s2, addr

Carga dirección

lui $at, addr31..16 ori $s2, $at, addr15..0

s2 ←32 addr31..0

move $s6, $t4

Mueve

addu $s6, $zero, $t4

s6 ←32 t431..0

Otras pseudoinstrucciones usuales son: beqz (salto si es cero), bnez (salta si no es cero), not (negación lógica), abs (valor absoluto), neg (negación), rem (resto de la división entera), sge (activa si mayor o igual), sgt (activa si mayor) y sle (activa si menor o igual). Para estudiar cómo se traducen estas pseudoinstrucciones (y cualquier otra que no se haya mencionado), el alumno puede utilizar el simulador MARS. Las pseudoinstrucciones se crearon para hacer más fácil la vida al programador. Sin embargo, como podemos observar, algunas pseudoinstrucciones se transforman en varias instrucciones reales (e incluso en algunos casos la traducción depende de los parámetros, como puede observarse en la pseudoinstrucción li). Esto supondrá un serio problema para el alumno en algunas prácticas posteriores, en las que deberá estudiar los programas a partir de las instrucciones reales que los componen (por ejemplo, para el cálculo del CPI3). Por este motivo, el alumno debe conocer cómo se traducen las pseudoinstrucciones que utilice en sus programas. Por otra parte, para evitar errores difíciles de detectar en un programa con pseudoinstrucciones debemos respetar escrupulosamente las reglas de uso de los registros (en particular, se recomienda no u...


Similar Free PDFs