Materia: #organizacion_del_computador_II

Tags: Memoria

Arquitectura Intel 64

Registros

Dentro de la arquitectura de Intel de 64 bits vamos a contar con cuatro tipos de registros.

Primero tenemos los registros de propósito general, los cuales son 16 registros de 64 bits cada uno. Estos son los que mas vamos a utilizar y pueden ver sus nombres en la tabla:

RAX RBX RCX RDX RSI RDI RBP RSP
R8 R9 R10 R11 R12 R13 R14 R15

Algunos de estos tienen funciones preestablecidas y no podremos usarlos con total libertad. Mas adelante esta explicado la función de cada uno.

Luego tenemos los registros XMM, los cuales son 16 registros de 128 bits de tamaño. El doble de los de propósito general. Estos registros cuentan con sus propias instrucciones, y suelen ser usadas al trabajar con algoritmos de modelo SIMD. Se encuentran por el nombre XMMn, donde n es un numero del 0 al 15.

Por otro lado, tenemos los registros de la FPU (floating point unit). Es decir, los registros de punto flotante, que tienen 80 bits de espacio: 64 para la mantisa, 14 para el exponente y 1 para el signo. Son registros especiales para manejar operaciones con números reales. Tienen nombre de la forma Rn, donde n es un numero del 0 al 7, inclusive.

Por ultimo están los registros MMX, los cuales son 8 registros de 64 bits. Su nombre consiste en MMn, con n entre 0 y 7. En particular estos registros ya están obsoletos, siguen estando en los modelos nuevos de Intel, pero ya no se les da uso.


Instrucciones

Como reglas generales, de acuerdo con la documentación disponible, las instrucciones de estos procesadores pueden obtener los operandos desde:

Del mismo modo, el resultado de una operación puede tener como destino para su almacenamiento:


Modos de direccionamiento

A la hora de utilizar las instrucciones, existen distintas formas de direccionar la memoria. Es decir, formas de indicarle al procesador a que celda de memoria queremos acceder.

Para empezar, tenemos el direccionamiento implícito. Se trata de instrucciones en las cuales el código de operación es suficiente para establecer que operación realizar y cual es el operando. Algunos ejemplos de estas instrucciones pueden ser:

clc            ; Para limpiar el flag de carry
stc            ; Para setear el flag de carry
cld            ; Para limpiar el flag de direccion
std            ; Para setear el flag de direccion
cli            ; Para limpiar el flag de insterrupciones
sti            ; Para setear el flag de insterrupciones

Por otro lado, tenemos el direccionamiento inmediato. Consiste en instrucciones donde el operando fuente viene dentro del código de la instrucción. En otras palabras, esta escrito explícitamente en el código.

add rsi, 10    ; Add es la operación de suma

En este ejemplo, podemos ver como la instrucción add le suma 10 a rsi , pero ese 10 no lo va a buscar en ningún lado de la memoria. En este caso, a 10 lo vamos a llamar un inmediato.

El mas importante y usado de todos: el direccionamiento a registro. Todos los operandos de la gran mayoría de instrucciones son registros, sin importar si son uno o dos. Y pueden ser de todos los tipos que vimos antes.

inc rsi        ; rsi = rsi + 1
mov rdi, rsi   ; rdi = rsi
add rdi, rsi   ; rdi = rdi + rsi

Por ultimo, tenemos el direccionamiento a memoria. Consiste en utilizar los valores de los registros como direcciones de memorias, como si fueran punteros.

mov rsi, [rdi]  ; Deja en rsi lo que haya en la direccion de memoria marcada por rdi

Los procesadores en los que vamos a trabajar, organizan la memoria como una secuencia de bytes, direccionables a través de su bus de adress. La memoria conectada a este bus se denomina memoria física. El espacio de direcciones que pueden volcarse sobre este bus se denomina direcciones físicas.

La memoria que diseño Intel se encuentra segmentada, por lo que para poder direccionar correctamente necesitamos dos valores: algún identificador del segmento en el que se encuentra lo que estemos buscando, y un offset, o dirección efectiva, a partir del inicio de ese segmento. A esta dirección, la combinación entre el selector de segmento y la dirección efectiva, Intel decidió llamarla dirección lógica.

Selector de segmento [16 bits] Offset (o dirección efectiva) [64 bits]

En general, el valor del selector de segmento se encuentra implícito, por lo que el programador no debería preocuparse por la segmentación. Aun así, es posible explicitar con que segmento se desea dirección un operando de memoria determinado. En caso de no especificarse un segmento, el procesador lo establecerá de acuerdo con la siguiente tabla:

Referencia a Registro Segmento Regla de selección por defecto
Instrucciones CS Segmento de código Cada opcode fetch
Pila SS Segmento de pila Todos los push y pop, cualquier referencia a memoria que utilice como registro base rbp o rsp
Datos locales DS Segmento de datos Cualquier referencia un dato, excepto en el stack o un destino de instrucción de string.
Strings destino ES Segmento de datos extra direccionado por ES Destino de instrucciones de manejo de strings.
Los registros mostrados en la tabla son reservado para el manejo de la segmentacion.

Podemos direccionar a memoria con una gran versatilidad de movimiento. En resumidas cuentas, para encontrar la dirección efectiva resuelve la siguiente cuenta:

DireccionEfectiva=Base+(Indice×Escala)+Desplazamiento

Donde Base es la dirección a secas a la que apunta el registro que estamos utilizando; Indice puede ser otro registro que indique una cantidad de "pasos" que queremos dar una vez en la dirección; Escala es un entero que va a escalar a Indice (específicamente, Escala solo puede tomar los valores 1, 2, 4 u 8); y Desplazamiento es la cantidad de bits que te quieres mover (para mas precisión). Desplazamiento solo puede tomar los valores 0, 8, 16 y 32.

Intel maneja la memoria con el modelo Little endian, así que hay que tener en cuenta que el orden de los bytes van a esta codificados "al revés" del sentido habitual.