Modos de Direccionamiento/Diseño de ISA

Anuncio
Modos de Direccionamiento+
Diseño de ISA
Organización del Computador 1
Verano 2016
Repaso
•
Vimos que una instrucción se compone de
•
•
OpCode
•
Fuente/s
•
Destino/s
CodOp
Fuente/s
¿Qué pueden ser estas Fuentes y Destinos?
•
Constantes
•
Registros
•
Direcciones de memoria
Destino/s
Repaso
•
¿Qué representan?
•
Constantes
•
Referencias a variables
•
Referencias a arreglos (arrays)
•
Referencias a sub-rutinas.
•
Estructuras de datos (listas, colas, etc.)
Modos de
Direccionamiento
(Parte 1)
Modos de direccionamiento
•
Del hecho de usar distintos tipos de operandos surge la
idea de tener distintos modos de direccionamiento
•
Es decir, distintas formas posibles de acceder a los
operandos (y además, optimizar la ejecución)
•
Algunos modos de direccionamiento usuales:
•
Inmediato
•
Registro
•
Directo (o absoluto)
•
Indirecto con registro
•
Indirecto
•
Desplazamiento
•
Indexado
Inmediato
•
El operando está en la misma instrucción (Cte).
•
Ejemplos (Orga1):
•
JMP 0x1110
•
CMP 0x00FF 0x11FF
OpCode
•
No hay acceso adicional a la memoria
•
Es rápido (pero poco flexible)
Cte
Directo
•
El operando está en la dirección de memoria
referenciada por DIR.
•
•
Es decir, el operando=[DIR]
OpCode
Ejemplo (Orga1):
•
NEG [0x1941]
•
Ideal para acceso a variables
•
Hay un único acceso adicional a memoria
DIR
Registro
•
El operando está en un registro del CPU
•
•
Es decir, operando=registro n OpCode
Rn
Ejemplo (Orga1):
•
NOT R0
•
Instrucción corta y rápida
•
No requiere acceso a memoria (ya está el operando en el CPU)
•
Espacio de direcciones (ie, cantidad de registros) limitado
Registro Indirecto
•
El operando está almacenada en la dirección de
memoria indicada por un registro
•
Es decir, operando=[Rn]
OpCode
Rn
•
Necesita un acceso a memoria menos que el
direccionamiento indirecto
•
Cómodo para acceder a arrays
Ejemplo
0xFF00 0xFF10
0xFF01 0x0000
•
0xFF20 0x0000
0xFF21 0x2222
Por ejemplo, supongamos que almacenamos una lista
dinámica como <PROX_DIRECCION,VALOR>
•
•
0xFF10 0xFF20
0xFF11 0x1111
El último elemento tiene PROX_DIRECCION=0x0000
¿Cómo escribimos un programa en lenguaje ORGA1
para que cuente la longitud de esta lista y lo almacene
en R0?
Ejemplo
0xFF00 0xFF10
0xFF01 0x0000
0xFF10 0xFF20
0xFF11 0x1111
0xFF20 0x0000
0xFF21 0x2222
R0:=0
R1 := 0xFF00
Mientras (R1!=0x0000)
R0:=R0+1
R1:=[R1]
Fin Mientras
Pseudo-código
Registro Indirecto
0xFF00 0xFF10
0xFF01 0x0000
Inicio
0xFF10 0xFF20
0xFF11 0x1111
0xFF20 0x0000
0xFF21 0x2222
MOV R0, 0x0000
MOV R1, 0xFF00
Mientras: CMP [R1], 0x0000
JE FinMientras
ADD R0, 0x0001
MOV R1,[R1]
FinMientras: JMP Mientras
Ensamblador Orga1
Acceso a arreglos
0x0000 0x1111 0x2222 0x3333 0x4444
0xFF00 0xFF01 0xFF02 0xFF03 0xFF04
Inicio
•
Por ejemplo, supongamos que almacenamos un
arreglo de 5 dimensiones a partir de la dirección
0xFF00
•
¿Cómo escribimos un programa en lenguaje
ORGA1 para que sume las componentes del
arreglo y lo almacene en R0?
Acceso a arreglos
0x0000 0x1111 0x2222 0x3333 0x4444
0xFF00 0xFF01 0xFF02 0xFF03 0xFF04
Inicio
R0:=0
R1 := 0xFF00
R2 := 0x0000
Mientras (R2!=0x0005)
R0:=R0+[R1]
R1:=R1+1
R2:=R2+1
Fin Mientras
Pseudo-código
Acceso a arreglos
0x0000 0x1111 0x2222 0x3333 0x4444
0xFF00 0xFF01 0xFF02 0xFF03 0xFF04
Inicio
MOV R0, 0x0000
MOV R1, 0xFF00
MOV R2, 0x0000
Mientras:
CMP R2,0x0005
JE FinMientras
ADD R0, [R1]
ADD R1, 0x0001
ADD R2, 0x0001
JMP Mientras
FinMientras:
…
Assembler
Orga1
Indirecto
•
•
El operando está en la dirección de memoria apuntada
por el contenido de la dirección
•
Es decir, operando=[[Dir]]
•
Típico para acceder a listas, arreglos u otras
estructuras dinámicas
OpCode
Necesita 2 accesos a memoria:
•
1ro: obtener el puntero P almacenado en Dir
•
2do: obtener el operando almacenado en P.
Dir
Indirecto
0xFF00 0xFF10
0xFF01 0x0000
0xFF10 0xFF20
0xFF11 0x1111
0xFF20 0x0000
0xFF21 0x2222
R0:=0
[p_actual] := 0xFF00
Mientras ([p_actual]!=0x0000)
R0:=R0+1
[actual]:=[[p_actual]]
Fin Mientras
Pseudo-código
Indirecto
0xFF00 0xFF10
0xFF01 0x0000
0xFF10 0xFF20
0xFF11 0x1111
0xFF20 0x0000
0xFF21 0x2222
p_actual: DW 0x0000
Inicio
MOV R0, 0x0000
MOV [p_actual] , 0xFF00
Mientras: CMP [p_actual], 0x0000
JE FinMientras
Ensamblador Orga1
ADD R0, 0x0001
MOV [p_actual],[[p_actual]]
JMP Mientras
FinMientras: …
Desplazamiento
•
El operando está almacenado en la dirección surgida de
sumar el valor del registro y del desplazamiento (también
llamado offset)
•
Es decir, operando=[Rn+D]
OpCode
•
Ideal para acceder a campos de registros
•
También para arrays de registros
•
Rn se mueve dentro del array
•
D selecciona el campo
Rn
D
Indexado
•
El operando está almacenado en la dirección
producto de sumar una dirección con el valor de un
registro
•
•
OpCode
Dir
Similar al direccionamiento de desplazamiento
•
•
Es decir, operando=[Dir+Rn]
Diferencia: D puede ser bastante menor al espacio
de direcciones (4 bits vs. 32 bits)
Ideal para arreglos
Rn
Acceso a arreglos Indexado
0x0000 0x1111 0x2222 0x3333 0x4444
0xFF00 0xFF01 0xFF02 0xFF03 0xFF04
Inicio
MOV R0,0x0000
MOV R1,0x0000
Mientras: CMP R1,0x0005
JE FinMientras
ADD R0, [0xFF00 +R1]
ADD R1, 0x0001
JMP Mientras
FinMientras: …
Assembler
Orga1
Indexado con escala
•
El operando se encuentra en la posición resultado
de sumar la dirección al registro multiplicado por la
escala OpCode
Dir
Rn
Escala
•
•
Es decir, operando=[Dir+Rn*Escala]
Ideal para arreglos de estructuras
Indexado con escala
•
Supongamos que un producto de un supermercado
es representado con 3 enteros <Id,Precio,Stock>
•
Id0
Si un arreglo con 3 productos se almacena a
partir de la dirección 0xFF00 la memoria estará
ocupada del siguiente modo:
Precio0 Stock0
Id1
Precio1 Stock1
Id2
Precio2 Stock2
0xFF00 0xFF01 0xFF02 0xFF03 0xFF04 0xFF05 0xFF06 0xFF07 0xFF08
Inicio
Indexado con escala
Producto0
Id0
Precio0 Stock0
Producto1
Id1
Precio1 Stock1
Producto2
Id2
Precio2 Stock2
0xFF00 0xFF01 0xFF02 0xFF03 0xFF04 0xFF05 0xFF06 0xFF07 0xFF08
Inicio
•
Para sumar los stocks de todos los productos
puedo utilizar el modo indexado con
desplazamiento
•
ADD R0, [0xFF02+R1*3]
Modos de direccionamiento
•
•
Facilitan el acceso a los operandos
•
Arreglos
•
Matrices
•
Listas
•
Registros (Records)
La ausencia de un modo de direccionamiento no
impide el acceso al operando.
Modos de direccionamiento
0x0800 0x0900
Memoria
0x0900 0x1000
Registros
0x1000 0x0500
Instrucción Máq. Orga1
MOV R0,0x0800
MOV R0,[0x0800]
Indirecto
MOV R0,R1
Registro
MOV R0,[R1+0x0800]
…
R1 0x0800
Modo de
Valor final de
Direccionamiento fuente
R0
Inmediato
Directo
MOV R0,[[0x0800]]
MOV R0,[R1]
R0
Indirecto Registro
Indexado
Modos de direccionamiento
0x0800 0x0900
Memoria
0x0900 0x1000
Registros
0x1000 0x0500
Instrucción Máq. Orga1
MOV R0,0x0800
MOV R0,[0x0800]
Indirecto
MOV R0,R1
Registro
MOV R0,[R1+0x0800]
…
R1 0x0800
Modo de
Valor final de
Direccionamiento fuente
R0
Inmediato
0x0800
Directo
MOV R0,[[0x0800]]
MOV R0,[R1]
R0
Indirecto Registro
Indexado
Modos de direccionamiento
0x0800 0x0900
Memoria
0x0900 0x1000
Registros
0x1000 0x0500
Instrucción Máq. Orga1
MOV R0,0x0800
MOV R0,[0x0800]
Indirecto
MOV R0,R1
Registro
MOV R0,[R1+0x0800]
…
R1 0x0800
Modo de
Valor final de
Direccionamiento fuente
R0
Inmediato
0x0800
Directo
0x0900
MOV R0,[[0x0800]]
MOV R0,[R1]
R0
Indirecto Registro
Indexado
Modos de direccionamiento
0x0800 0x0900
Memoria
0x0900 0x1000
Registros
0x1000 0x0500
Instrucción Máq. Orga1
MOV R0,0x0800
MOV R0,[0x0800]
Indirecto
MOV R0,R1
Registro
MOV R0,[R1+0x0800]
…
R1 0x0800
Modo de
Valor final de
Direccionamiento fuente
R0
Inmediato
0x0800
Directo
0x0900
MOV R0,[[0x0800]]
MOV R0,[R1]
R0
Indirecto Registro
Indexado
0x1000
Modos de direccionamiento
0x0800 0x0900
Memoria
0x0900 0x1000
Registros
0x1000 0x0500
Instrucción Máq. Orga1
MOV R0,0x0800
MOV R0,[0x0800]
R0
…
R1 0x0800
Modo de
Valor final de
Direccionamiento fuente
R0
Inmediato
0x0800
Directo
0x0900
MOV R0,[[0x0800]]
Indirecto
0x1000
MOV R0,R1
Registro
0x0800
MOV R0,[R1]
MOV R0,[R1+0x0800]
Indirecto Registro
Indexado
Modos de direccionamiento
0x0800 0x0900
Memoria
0x0900 0x1000
Registros
0x1000 0x0500
Instrucción Máq. Orga1
MOV R0,0x0800
MOV R0,[0x0800]
R0
…
R1 0x0800
Modo de
Valor final de
Direccionamiento fuente
R0
Inmediato
0x0800
Directo
0x0900
MOV R0,[[0x0800]]
Indirecto
0x1000
MOV R0,R1
Registro
0x0800
Indirecto Registro
0x0900
MOV R0,[R1]
MOV R0,[R1+0x0800]
Indexado
Modos de direccionamiento
0x0800 0x0900
Memoria
0x0900 0x1000
Registros
0x1000 0x0500
Instrucción Máq. Orga1
MOV R0,0x0800
MOV R0,[0x0800]
R0
…
R1 0x0800
Modo de
Valor final de
Direccionamiento fuente
R0
Inmediato
0x0800
Directo
0x0900
MOV R0,[[0x0800]]
Indirecto
0x1000
MOV R0,R1
Registro
0x0800
Indirecto Registro
0x0900
Indexado
0x0500
MOV R0,[R1]
MOV R0,[R1+0x0800]
Diseño de una
Arquitectura (ISA)
(Parte 2)
Diseño de ISA
•
Tenemos que considerar:
•
Tipos de operaciones
•
Números de bits por instrucción
•
Número de operandos por instrucción
•
•
Operandos implícitos y explícitos
•
Ubicación de los campos
•
Tamaño y tipo de los operandos
Uso de stack, registros, etc.
Algunas métricas
•
Memoria principal ocupada por el programa
•
Tamaño de la instrucción (en bits)
•
Code density: tratar de que las instrucciones
ocupen lo menos posible
•
Complejidad de la instrucción
•
Número total de instrucciones disponibles
Algunas preguntas a
responder
•
Tamaño de la instrucción: ¿corto? ¿largo? ¿variable?
•
¿Cuántos bits para el OpCode?
•
•
¿Cuántos bits para acceder a los operandos?
•
•
Limita la cantidad de instrucciones
Limita la cantidad de memoria accesible
¿Cuántos registros?
•
Más registros es más cómodo para el programador, pero
más costoso para la construcción
Algunas preguntas a
responder
•
Memoria:
•
¿Direccionamiento por word o byte?
•
¿Endianness?
•
¿Cuántos/cuáles son los modos de
direccionamiento?
Tamaño Memoria
•
Tamaño de la memoria=
Tamaño unidad direccionable x cant. direcciones
•
Ejemplo:
•
Tamaño unidad direccionable = 1Byte
•
Cant. direcciones = 2^16 =65536 direcciones
•
Tamaño Memoria = 65536 x 1 B = 65536 B = 64 KB
Cantidad de Direcciones de
Memoria
•
Cantidad de direcciones =
Tam. de la Memoria / Tam. Unidad Direccionable
•
Ejemplo:
•
Tamaño de la Memoria = 8 MB
•
Tamaño Unidad Direccionable = 2 B
•
Cant. de Direcciones = 8 MB/2B = 4M
=4x1024x1024= 4.194.304 direcciones
Cantidad de bits para
direcciones de Memoria
•
Cantidad de bits para direcciones =
log2(Cantidad de direcciones)
•
Ejemplo:
•
Cant. de Direcciones = 4.194.304
•
Cant. de bits para codificar direcciones =
log2(4.194.304)= 22 bits
Operandos
•
3 operandos: RISC y Mainframes
•
•
•
2 operandos: Intel, Motorola
•
A = A+B
•
(Al menos uno debe ser un registro)
1 operando: arquitecturas de acumulador
•
•
AC = AC + A (+operando implícito: registro acumulador)
0 operandos: arquitecturas de pila
•
•
A = B+C
push(pop()+pop()) (+operando implícito: pila)
Arquitecturas super-escalares (ejemplo: VLIW)
Algunas ISAs
Ortogonalidad
•
Máxima ortogonalidad: cualquier instrucción
puede ser usada con cualquier modo de
direccionamiento
•
Es una característica “elegante" pero muy costosa:
•
Implica tener muchas instrucciones
•
Algunas quizás poco usadas o fácilmente
reemplazables
Ejemplo
•
¿Qué podemos deducir de este formato de
instrucción?
Ejemplo
32b
32b
32b
•
Instrucciones de longitud variable
•
Tamaño: 32 bits, 64bits o 96bits
Ejemplo
}
8 bits para Opcode =2ˆ8 instrucciones=256
Ejemplo
5 bits para identificar registros
}
=2ˆ5 registros=32
Ejemplo
3 bits para identificar modos de direccionamiento
}
=2ˆ3 modos de direc.=8
Ejemplo
}
4 bits para indicar desplazamiento o escala
Ejemplo
32 bits para direcciones/datos/desplazamiento
•
Es necesario leer una segunda palabra valores
inmediatos/direcciones/etc.
Formato de Instrucción
•
El tamaño de las instrucciones depende fuertemente del
número de operandos que soporta la Arquitectura
•
No todas las instrucciones requieren el mismo número
de operandos
•
Por ejemplo, la operación RET ni siquiera necesita
operando, qué podemos hacer con el espacio que
sobra
•
Rta: podríamos utilizar códigos de operación
variables
Ejemplo
•
•
Supongamos una arquitectura con 16 registros, 4K
direcciones de memoria.
•
Los registros se codifican con 4 bits (2^4=16)
•
Las direcciones se codifican con 12 bits
(2^12=4K)
Si la longitud de instrucción es fija de 16 bits,
¿cuántas instrucciones puede tener la
Arquitectura?
OpCode Fijo
•
2^4 = 16 instrucciones:
•
Algunas con 1 dirección de memoria de operando
•
Otros con hasta 3 registros como operandos
OpCode Fijo
•
Supongamos que se necesita únicamente 2
instrucciones con acceso a memoria
0000
0001
0010
…
1111
R1
DIR
Tipo 1: 2 instrucciones de 1
dirección de memoria
R2
Tipo 2: 14 instrucciones de 3
registros
R3
•
Si el OpCode es fijo de 4 bits, quedan únicamente 14
instrucciones de a lo sumo 3 registros.
•
¿Qué pasa si el OpCode es variable?
OpCode Variable
0000
0001
DIR
Tipo 1: 2 instrucciones de 1
dirección de memoria
R2
R3
Tipo 2: 13 instrucciones de 3
registros
R2
Tipo 3: 15 instrucciones de 2
registros
0010
…
1110
R1
1111
0000
….
1110
R1
1111
0000
…
1110
R1
Tipo 4: 15 instrucciones de 1
registro
1111
0000
…
1111
Tipo 5: 16 instrucciones de 0
operandos
1111
1111
1111
OpCode Fijo vs. OpCode
Variable
•
El OpCode Variable nos permite un mayor
aprovechamiento del espacio de codificaciones
•
OpCode Fijo = 16 instrucciones
•
OpCode Variable = 61 instrucciones
Formato de Instrucción
Pentium
Modos de direccionamiento Pentium: 24!
Formato de Instrucción
Pentium
REP MOVS
0xF3
# Copia “CX” bytes de DS:SI hacia ES:DI
0xA4
Resumen
•
Modos de direccionamiento
•
•
Inmediato, Directo, Indirecto, Registro, etc.
Diseño de ISA:
•
Ortogonalidad, Formato de Instrucción
•
OpCode Fijo vs. OpCode Variable
Bibliografía
•
Tanenbaum - Capítulo 5
•
Stalling - Capítulo 11
•
Null - Capítulo 5
Descargar