Un registro de índice en la CPU de una computadora es un registro de procesador (o una ubicación de memoria asignada) [1] que se utiliza para señalar direcciones de operandos durante la ejecución de un programa. Es útil para recorrer cadenas y matrices . También se puede utilizar para almacenar iteraciones de bucles y contadores. En algunas arquitecturas se utiliza para leer/escribir bloques de memoria. Dependiendo de la arquitectura, puede ser un registro de índice dedicado o un registro de propósito general. [2] Algunos conjuntos de instrucciones permiten utilizar más de un registro de índice; en ese caso, los campos de instrucciones adicionales pueden especificar qué registros de índice utilizar. [3]
Generalmente, el contenido de un registro de índice se suma (en algunos casos se resta) a una dirección inmediata (que puede ser parte de la instrucción misma o estar contenida en otro registro) para formar la dirección "efectiva" de los datos reales (operando). Normalmente se proporcionan instrucciones especiales para probar el registro de índice y, si la prueba falla, se incrementa el registro de índice en una constante inmediata y se ramifica, normalmente al inicio del bucle. Aunque normalmente los procesadores que permiten que una instrucción especifique múltiples registros de índice suman el contenido, IBM tenía una línea de computadoras en las que el contenido se combinaba mediante OR. [4]
Los registros de índice han demostrado ser útiles para realizar operaciones con vectores y matrices y en el procesamiento de datos comerciales para navegar de un campo a otro dentro de los registros. En ambos usos, los registros de índice redujeron sustancialmente la cantidad de memoria utilizada y aumentaron la velocidad de ejecución.
En las primeras computadoras sin ninguna forma de direccionamiento indirecto , las operaciones de matriz debían realizarse modificando la dirección de instrucción, lo que requería varios pasos de programa adicionales y utilizaba más memoria de computadora, [5] un recurso escaso en las instalaciones de computadoras de la era temprana (así como en las primeras microcomputadoras dos décadas después).
Los registros de índice, comúnmente conocidos como líneas B en las primeras computadoras británicas, como registros B en algunas máquinas y como registros X [a] en otras, se usaron por primera vez en la computadora británica Manchester Mark 1 , en 1949. En general, los registros de índice se convirtieron en una parte estándar de las computadoras durante la segunda generación de la tecnología , aproximadamente entre 1954 y 1966. La mayoría de las máquinas [b] de la serie de mainframes IBM 700/7000 los tenían, comenzando con el IBM 704 en 1954, aunque eran opcionales en algunas máquinas más pequeñas como el IBM 650 y el IBM 1401 .
Las primeras "pequeñas máquinas" con registros de índice incluyen la AN/USQ-17 , alrededor de 1960, y la serie 9 de computadoras en tiempo real de Scientific Data Systems , de principios de la década de 1960.
El UNIVAC 1107 de 1962 tiene 15 registros X, cuatro de los cuales también eran registros A.
El GE-635 de 1964 tiene 8 registros X dedicados; sin embargo, también permite la indexación por el contador de instrucciones o por la mitad del registro A o Q.
El PDP-6 de Digital Equipment Corporation (DEC) , introducido en 1964, y el IBM System/360 , anunciado en 1964, no incluyen registros de índice dedicados; en su lugar, tienen registros de propósito general (llamados "acumuladores" en el PDP-6) que pueden contener valores numéricos o direcciones. La dirección de memoria de un operando es, en el PDP-6, la suma del contenido de un registro de propósito general y un desplazamiento de 18 bits y, en el System/360, la suma del contenido de dos registros de propósito general y un desplazamiento de 12 bits. [6] [7] La línea PDP-10 compatible de sucesores del PDP-6, y el IBM System/370 y los sucesores posteriores compatibles del System/360, incluido el actual z/Architecture , funcionan de la misma manera.
Las minicomputadoras Data General Nova de 1969 y su sucesora Eclipse , y la DEC PDP-11 de 1970 , también proporcionaban registros de propósito general (llamados "acumuladores" en Nova y Eclipse), en lugar de acumuladores y registros de índice separados, como lo hacían sus sucesoras Eclipse MV y VAX, las superminicomputadoras de 32 bits . En PDP-11 y VAX, se podía utilizar cualquier registro al calcular la dirección de memoria de un operando; en Nova, Eclipse y Eclipse MV, solo se podían utilizar los registros 2 y 3. [8] [9] [10]
El CDC STAR-100 de 1971 tiene un archivo de registros de 256 registros de 64 bits, 9 de los cuales están reservados. A diferencia de la mayoría de las computadoras, las instrucciones del STAR-100 solo tienen campos de registro y campos de operandos, por lo que los registros sirven más como registros de puntero que como registros de índice tradicionales.
Si bien el Intel 8008 de 1972 permitía el direccionamiento indirecto a través de pares de registros, el primer microprocesador con un verdadero registro de índice parece haber sido el Motorola 6800 de 1974 .
En 1975, el procesador MOS Technology 6502 de 8 bits tenía dos registros de índice 'X' e 'Y'. [11]
En 1978, el Intel 8086 , el primer procesador x86 , tenía ocho registros de 16 bits, denominados "de propósito general", todos los cuales pueden usarse como registros de datos enteros en la mayoría de las operaciones; cuatro de ellos, 'SI' (índice de origen), 'DI' (índice de destino), 'BX' (base) y 'BP' (puntero base), también se pueden utilizar al calcular la dirección de memoria de un operando, que es la suma de uno de esos registros y un desplazamiento, o la suma de uno de 'BX' o 'BP", uno de 'SI' o 'DI', y un desplazamiento. [12] El Intel 8088 de 1979 y los sucesores de 16 bits Intel 80186 , Intel 80188 e Intel 80286 funcionan de la misma manera. En 1985, el i386 , un sucesor de 32 bits de esos procesadores, que introdujo la versión IA-32 de 32 bits de la arquitectura x86, amplió los ocho registros de 16 bits a 32 bits, con "E" añadido al principio del nombre del registro; en IA-32, la dirección de memoria de un operando es la suma de uno de esos ocho registros, uno de siete de esos registros (el puntero de pila no está permitido como segundo registro aquí) multiplicado por 1, 2, 4 u 8, y un desplazamiento. [13] : 3-11–3-12, 3-22–3-23 El Advanced Micro Devices Opteron , cuyo primer modelo fue lanzado en 2003, introdujo x86-64 , la versión de 64 bits del conjunto de instrucciones x86; en x86-64, los registros de propósito general se extendieron a 64 bits, y se agregaron ocho registros de propósito general adicionales; la dirección de memoria de un operando es la suma de dos de esos 16 registros y un desplazamiento. [14] [13] : 3–12, 3–24
Los conjuntos de instrucciones de computación de conjunto de instrucciones reducidas (RISC) introducidos en los años 1980 y 1990 proporcionan todos registros de propósito general que pueden contener valores numéricos o valores de dirección. En la mayoría de esos conjuntos de instrucciones, hay 32 registros de propósito general (en algunos de esos conjuntos de instrucciones, el valor de uno de esos registros está cableado a cero) que podrían usarse para calcular la dirección del operando; no tenían registros de índice dedicados. En la versión de 32 bits de la arquitectura ARM , desarrollada por primera vez en 1985, hay 16 registros designados como "registros de propósito general", pero solo 13 de ellos pueden usarse para todos los propósitos, y el registro R15 contiene el contador de programa . La dirección de memoria de una instrucción de carga o almacenamiento es la suma de cualquiera de los 16 registros y un desplazamiento u otro de los registros con la excepción de R15 (posiblemente desplazado a la izquierda para escalar). [15] En la versión de 64 bits de la arquitectura ARM, hay 31 registros de propósito general de 64 bits más un puntero de pila y un registro cero; la dirección de memoria de una instrucción de carga o almacenamiento es la suma de cualquiera de los 31 registros y un desplazamiento u otro de los registros. [16]
A continuación se muestra un ejemplo simple del uso de un registro de índice en un pseudocódigo en lenguaje ensamblador que suma una matriz de 100 entradas de palabras de 4 bytes:
Limpiar acumulador Load_index 400,index2 //carga 4*tamaño de matriz en el registro de índice 2 (index2)loop_start : Agregar_palabra_al_acumulador array_start,index2 //Agrega a AC la palabra en la dirección (array_start + index2) Loop_start,4,index2 //bucle decrementando en 4 hasta que el registro de índice sea cero