Индексный регистр в ЦП компьютера — это регистр процессора (или назначенная ячейка памяти) [1], используемый для указания на адреса операндов во время выполнения программы. Он полезен для пошагового прохождения строк и массивов . Он также может использоваться для хранения итераций цикла и счетчиков. В некоторых архитектурах он используется для чтения/записи блоков памяти. В зависимости от архитектуры это может быть выделенный индексный регистр или регистр общего назначения. [2] Некоторые наборы инструкций позволяют использовать более одного индексного регистра; в этом случае дополнительные поля инструкций могут указывать, какие индексные регистры использовать. [3]
Обычно содержимое индексного регистра добавляется (в некоторых случаях вычитается) к непосредственному адресу (который может быть частью самой инструкции или храниться в другом регистре) для формирования «эффективного» адреса фактических данных (операнда). Специальные инструкции обычно предоставляются для проверки индексного регистра и, если тест не пройден, увеличивают индексный регистр на непосредственную константу и выполняют переходы, как правило, к началу цикла. В то время как обычно процессоры, которые позволяют инструкции указывать несколько индексных регистров, складывают содержимое вместе, у IBM была линейка компьютеров, в которых содержимое объединялось с помощью операции or'd. [4]
Индексные регистры оказались полезными для выполнения векторных / массивных операций и в коммерческой обработке данных для навигации от поля к полю в записях. В обоих случаях индексные регистры существенно сократили объем используемой памяти и увеличили скорость выполнения.
В ранних компьютерах без какой-либо формы косвенной адресации операции с массивами приходилось выполнять путем изменения адреса инструкции, что требовало нескольких дополнительных шагов программы и расходовало больше памяти компьютера [5] , дефицитного ресурса в компьютерных установках ранней эпохи (а также в первых микрокомпьютерах два десятилетия спустя).
Индексные регистры, обычно известные как B-линии в ранних британских компьютерах, как B-регистры на некоторых машинах и X-регистры [a] на других, были впервые использованы в британском компьютере Manchester Mark 1 в 1949 году. В целом, индексные регистры стали стандартной частью компьютеров во втором поколении технологии , примерно в 1954–1966 годах. Большинство [b] машин в серии мэйнфреймов IBM 700/7000 имели их, начиная с IBM 704 в 1954 году, хотя они были опциональными на некоторых меньших машинах, таких как IBM 650 и IBM 1401 .
Ранние «малые машины» с индексными регистрами включают AN/USQ-17 , выпущенный около 1960 года, и 9-ю серию компьютеров реального времени от Scientific Data Systems , выпущенную в начале 1960-х годов.
UNIVAC 1107 1962 года имел 15 X-регистров, четыре из которых были также A-регистрами.
GE-635 1964 года выпуска имел 8 выделенных X-регистров; однако он также допускал индексацию по счетчику команд или по половине регистра A или Q.
Digital Equipment Corporation (DEC) PDP-6 , представленный в 1964 году, и IBM System/360 , анонсированный в 1964 году, не включают в себя выделенные индексные регистры; вместо этого у них есть регистры общего назначения (называемые «аккумуляторами» в PDP-6), которые могут содержать либо числовые значения, либо адреса. Адрес памяти операнда в PDP-6 представляет собой сумму содержимого регистра общего назначения и 18-битного смещения, а в System/360 — сумму содержимого двух регистров общего назначения и 12-битного смещения. [6] [7] Совместимая линейка PDP-10 преемников PDP-6, а также IBM System/370 и более поздние совместимые преемники System/360, включая текущую z/Architecture , работают таким же образом.
Миникомпьютеры Data General Nova 1969 года и его преемник Eclipse , а также DEC PDP-11 1970 года также предоставляли регистры общего назначения (называемые «аккумуляторами» в Nova и Eclipse), а не отдельные аккумуляторы и индексные регистры, как это делали их преемники Eclipse MV и 32-битные суперминикомпьютеры VAX . В PDP-11 и VAX любой регистр мог использоваться при вычислении адреса памяти операнда; в Nova, Eclipse и Eclipse MV могли использоваться только регистры 2 и 3. [8] [9] [10]
У CDC STAR-100 1971 года есть регистровый файл из 256 64-битных регистров, 9 из которых зарезервированы. В отличие от большинства компьютеров, инструкции STAR-100 имеют только поля регистров и поля операндов, поэтому регистры служат скорее как регистры указателей, чем как традиционные индексные регистры.
Хотя Intel 8008 1972 года позволял осуществлять косвенную адресацию через пары регистров, первым микропроцессором с настоящим индексным регистром, по-видимому, стал Motorola 6800 1974 года .
В 1975 году 8-битный процессор MOS Technology 6502 имел два индексных регистра «X» и «Y». [11]
В 1978 году Intel 8086 , первый процессор x86 , имел восемь 16-битных регистров, называемых «универсальными», каждый из которых мог использоваться как целочисленный регистр данных в большинстве операций; Четыре из них, «SI» (исходный индекс), «DI» (индекс назначения), «BX» (база) и «BP» (указатель базы), также могут использоваться при вычислении адреса памяти операнда, который является суммой одного из этих регистров и смещения, или суммой одного из «BX» или «BP», одного из «SI» или «DI» и смещения. [12] Intel 8088 1979 года и 16-разрядные преемники Intel 80186 , Intel 80188 и Intel 80286 работают одинаково. В 1985 году i386 , 32-разрядный преемник этих процессоров, представив 32-разрядную версию архитектуры x86 IA-32 , расширил восемь 16-разрядных регистров до 32 бит, с добавлением «E» в начало имени регистра; в IA-32 память адрес операнда — это сумма одного из этих восьми регистров, одного из семи из этих регистров (указатель стека не допускается в качестве второго регистра здесь), умноженного на 1, 2, 4 или 8, и смещения. [13] : 3-11–3-12, 3-22–3-23 Advanced Micro Devices Opteron , первая модель которого была выпущена в 2003 году, представила x86-64 , 64-битную версию набора инструкций x86; в x86-64 регистры общего назначения были расширены до 64 бит, и было добавлено восемь дополнительных регистров общего назначения; адрес памяти операнда — это сумма двух из этих 16 регистров и смещения. [14] [13] : 3–12, 3–24
Наборы инструкций RISC ( Reduced Command Set Computing ), представленные в 1980-х и 1990-х годах, все предоставляют регистры общего назначения, которые могут содержать либо числовые значения, либо значения адреса. В большинстве этих наборов инструкций имеется 32 регистра общего назначения (в некоторых из этих наборов инструкций значение одного из этих регистров жестко привязано к нулю), которые можно использовать для вычисления адреса операнда; у них не было выделенных индексных регистров. В 32-разрядной версии архитектуры ARM , впервые разработанной в 1985 году, имеется 16 регистров, обозначенных как «регистры общего назначения», но только 13 из них могут использоваться для всех целей, при этом регистр R15 содержит счетчик программ . Адрес памяти инструкции загрузки или сохранения представляет собой сумму любого из 16 регистров и либо смещения, либо другого регистра, за исключением R15 (возможно, сдвинутого влево для масштабирования). [15] В 64-битной версии архитектуры ARM имеется 31 64-битный регистр общего назначения, а также указатель стека и нулевой регистр; адрес памяти инструкции загрузки или сохранения представляет собой сумму любого из 31 регистра и либо смещения, либо другого регистра. [16]
Вот простой пример использования индексного регистра в псевдокоде на языке ассемблера, который суммирует массив из 100 записей 4-байтовых слов:
Очистить_аккумулятор Load_index 400,index2 //загрузить 4*размер массива в индексный регистр 2 (index2)loop_start : Add_word_to_accumulator array_start,index2 //Добавить к AC слово по адресу (array_start + index2) Branch_and_decrement_if_index_not_zero loop_start,4,index2 //цикл, уменьшающийся на 4, пока индексный регистр не станет равным нулю