Обзор работы с индексными регистрами » History » Version 44
Version 43 (krufter_multiclet, 05/08/2013 05:23 PM) → Version 44/48 (krufter_multiclet, 05/08/2013 05:24 PM)
h1. Обзор работы с индексными регистрами
Индексные регистры используются для косвенной адресации. Логическая структура индексного регистра:
| *Номера битов*| 63..48 | 47..32 | 31..0 |
| *Обозначение* | Индекс(Index)| Маска(Mask) | База(Base) |
Для обращения к какому-либо регистру данного типа используются номера от 32 до 39.
Имен у данного типа регистров нет. В общем случае (см. исключения в описании конкретной
команды в разделе «Система команд ассемблера») при использовании регистра данного типа в
качестве аргумента операции значение этого аргумента формируется согласно следующему
алгоритму:
1. вычисление исполнительного адреса, согласно следующей формуле:
_Address_ = _Index_ + _Base_
2. обращение к памяти данных по исполнительному адресу для чтения/записи
значения аргумента согласно типу используемой команды.
Модификация значения индексного регистра осуществляется аппаратно по завершению
параграфа в том случае, если установлен соответствующий бит регистра MODR маски
изменения индексных регистров (см. раздел «Регистры управления»), согласно следующей
формуле:
_Index_ = ((_Index_ | ∼ _Mask_ ) + 1) & _Mask_,
где | — операция побитового «ИЛИ», & — операция побитового «И», ∼ — операция
побитового инвертирования.
В двух выше приведённых формулах используется целочисленная 32-х разрядная
арифметика. Значения старших 16 разрядов (с 16 по 31) полей Индекс (Index) и Маска
(Mask)заполняются нулями.
Рассмотрим подробнее работу с индексными регистрами мультиклеточного процессора.
h3. 1) Отличие индексных регистров от РОНов
В командах ассемблера, при использовании РОНов(регистров общего назначения) в качестве аргумента,
происходит работа с текущим значением РОНа. Например:
<pre>
pre:
getl 5
setl #1, @1
jmp paragraph1
complete
paragraph1:
addl #1, 5
setl #1, @1
jmp paragraph2
complete
</pre>
В параграфе "pre" мы положили в первый РОН значение "5". В параграфе "paragraph1" командой "addl"
выполнится сложение, результат которого(5+5=10) запишется в первый РОН.
В командах ассемблера, при использовании индексных регистров качестве аргумента,
происходит работа со значением, размещённым в памяти по адресу который формирует индексный регистр.
Адрес, формируемый индексным регистром равен сумме _Индекса_ и _Базы_ регистра (_Address_ = _Index_ + _Base_).
Рассмотрим пример:
<pre>
pre:
getl 4
setl #32, @1
getl 6
wrl @1, @3
jmp paragraph1
complete
paragraph1:
addl #32, 5
setl #32, @1
jmp paragraph2
complete
</pre>
В параграфе "pre" мы положили в 32-й индексный регистр значение "4". В этом же параграфе записывается
в память данных по адресу 4 значение равное 6. В параграфе "paragraph1" командой "addl"
выполнится сложение значения, размещённого в памяти данных по адресу, сформированному индексным регистром.
В нашем случае _Index_ = 0, _Base_ = 4, следовательно адрес в памяти данных будет равен 4.
По 4 адресу в памяти данных располагается значение 6, т.е. результатом операции "addl" будет число 11 (6+5).
Результат сложения мы поместим в индексный регистр номер 32.
+Примечание:+ команды _setl_ и _getl_ оперируют с самим индексным регистром и не обращаются в память по значению,
формируемому индексным регистром.
h3. 2) Автоматический инкремент индексного регистра
Модификация значения индексного регистра осуществляется аппаратно по завершению
параграфа в том случае, если установлен соответствующий бит регистра MODR маски
изменения индексных регистров.
Рассмотрим заполнение индексного регистра для модификации:
<pre>
I = (K - N + 1) * L
M = (K - 1) * L
B = 0
а) К - ближайшее к N число, кратное степени 2, K >= N
б) 0 <= I < 65536
в) 0 <= M < 65536
где I - Index, M - Mask, B - Base
N - число итераций
L - шаг итераций
</pre>
Условия модификации:
1) значение индексного регистра только инкрементируется
(_при достижении последней итерации цикл модификации начинается заново_)
2) шаг может быть только равным числу кратному степени 2 и не равен нулю.
(1, 2, 4, 8, 16 ...)
База задаёт лишь смещение значений индексного регистра.
*
h3. 3) Рассмотрим модификацию индексного регистра на примерах* примерах
а) Пусть необходим счётчик на 10000 итераций с шагом 1.
<pre>
N = 10000, L = 1;
Найдём значения I, M, B
1) I = (K-N+1)*L = (16384-10000+1)*1 = 6385
К выбиралось как ближайшее к N число кратное степени 2,
т.е. 2^14 - 16384
2) M = (K-1)*L = (16384-1)*1 = 16383
3) B = 0
</pre>
Индексный регистр номер 32 будет изменяться от 6385 до 16383, после
16383 индексный регистр примет значение 0. В результате изменения регистра
от 6385 до 0 мы получим 10000 итераций с шагом изменения 1 по завершению параграфа.
Если задать значение базы, например B = 4, то индексный регистр 32 будет
изменяться от 6389 до 16387, причём следующее значение после 16387 будет 4.
Пример на ассемблере с модификацией индексного регистра будет выглядеть следующим
образом:
<pre>
set_modr:
getl (6385<<16)|16383 //заполняем индекс и маску
patch @1, 0 //склеиваем маску индекс и базу в 64 разряда
setq #32, @1 //записываем значение в регистр
setl #MODR, 1 //разрешаем модификацию первого индексного регистра
jmp paragraph64
complete
paragraph64:
exa #32 //получаем значение индекс + база
je @1, part2 //условный переход, проверка на ноль
jne @2, paragraph64
complete
</pre>
б) Пусть необходим счётчик на 5300 итераций с шагом 4.
<pre>
N = 5300, L = 4;
Найдём значения I, M, B
1) I = (K-N+1)*L = (8192-5300+1)*4 = 11572
К выбиралось как ближайшее к N число кратное степени 2,
т.е. 2^13 - 8192
2) M = (K-1)*L = (8192-1)*4 = 32764
3) B = 0
</pre>
Индексный регистр номер 32 будет изменяться от 11572 до 32764, после
32764 индексный регистр примет значение 0. В результате изменения регистра
от 11572 до 0 мы получим 5300 итераций с шагом изменения 4 по завершению параграфа.
Если задать значение базы, например B = 6, то индексный регистр 32 будет
изменяться от 11578 до 32780, причём следующее значение после 32780 будет 6.
Пример на ассемблере с модификацией индексного регистра будет выглядеть следующим
образом:
<pre>
set_modr:
getl (11572<<16)|32764 //заполняем индекс и маску
patch @1, 0 //склеиваем маску индекс и базу в 64 разряда
setq #32, @1 //записываем значение в регистр
setl #MODR, 1 //разрешаем модификацию первого индексного регистра
jmp paragraph64
complete
paragraph64:
exa #32 //получаем значение индекс + база
je @1, part2 //условный переход, проверка на ноль
jne @2, paragraph64
complete
</pre>
Индексные регистры используются для косвенной адресации. Логическая структура индексного регистра:
| *Номера битов*| 63..48 | 47..32 | 31..0 |
| *Обозначение* | Индекс(Index)| Маска(Mask) | База(Base) |
Для обращения к какому-либо регистру данного типа используются номера от 32 до 39.
Имен у данного типа регистров нет. В общем случае (см. исключения в описании конкретной
команды в разделе «Система команд ассемблера») при использовании регистра данного типа в
качестве аргумента операции значение этого аргумента формируется согласно следующему
алгоритму:
1. вычисление исполнительного адреса, согласно следующей формуле:
_Address_ = _Index_ + _Base_
2. обращение к памяти данных по исполнительному адресу для чтения/записи
значения аргумента согласно типу используемой команды.
Модификация значения индексного регистра осуществляется аппаратно по завершению
параграфа в том случае, если установлен соответствующий бит регистра MODR маски
изменения индексных регистров (см. раздел «Регистры управления»), согласно следующей
формуле:
_Index_ = ((_Index_ | ∼ _Mask_ ) + 1) & _Mask_,
где | — операция побитового «ИЛИ», & — операция побитового «И», ∼ — операция
побитового инвертирования.
В двух выше приведённых формулах используется целочисленная 32-х разрядная
арифметика. Значения старших 16 разрядов (с 16 по 31) полей Индекс (Index) и Маска
(Mask)заполняются нулями.
Рассмотрим подробнее работу с индексными регистрами мультиклеточного процессора.
h3. 1) Отличие индексных регистров от РОНов
В командах ассемблера, при использовании РОНов(регистров общего назначения) в качестве аргумента,
происходит работа с текущим значением РОНа. Например:
<pre>
pre:
getl 5
setl #1, @1
jmp paragraph1
complete
paragraph1:
addl #1, 5
setl #1, @1
jmp paragraph2
complete
</pre>
В параграфе "pre" мы положили в первый РОН значение "5". В параграфе "paragraph1" командой "addl"
выполнится сложение, результат которого(5+5=10) запишется в первый РОН.
В командах ассемблера, при использовании индексных регистров качестве аргумента,
происходит работа со значением, размещённым в памяти по адресу который формирует индексный регистр.
Адрес, формируемый индексным регистром равен сумме _Индекса_ и _Базы_ регистра (_Address_ = _Index_ + _Base_).
Рассмотрим пример:
<pre>
pre:
getl 4
setl #32, @1
getl 6
wrl @1, @3
jmp paragraph1
complete
paragraph1:
addl #32, 5
setl #32, @1
jmp paragraph2
complete
</pre>
В параграфе "pre" мы положили в 32-й индексный регистр значение "4". В этом же параграфе записывается
в память данных по адресу 4 значение равное 6. В параграфе "paragraph1" командой "addl"
выполнится сложение значения, размещённого в памяти данных по адресу, сформированному индексным регистром.
В нашем случае _Index_ = 0, _Base_ = 4, следовательно адрес в памяти данных будет равен 4.
По 4 адресу в памяти данных располагается значение 6, т.е. результатом операции "addl" будет число 11 (6+5).
Результат сложения мы поместим в индексный регистр номер 32.
+Примечание:+ команды _setl_ и _getl_ оперируют с самим индексным регистром и не обращаются в память по значению,
формируемому индексным регистром.
h3. 2) Автоматический инкремент индексного регистра
Модификация значения индексного регистра осуществляется аппаратно по завершению
параграфа в том случае, если установлен соответствующий бит регистра MODR маски
изменения индексных регистров.
Рассмотрим заполнение индексного регистра для модификации:
<pre>
I = (K - N + 1) * L
M = (K - 1) * L
B = 0
а) К - ближайшее к N число, кратное степени 2, K >= N
б) 0 <= I < 65536
в) 0 <= M < 65536
где I - Index, M - Mask, B - Base
N - число итераций
L - шаг итераций
</pre>
Условия модификации:
1) значение индексного регистра только инкрементируется
(_при достижении последней итерации цикл модификации начинается заново_)
2) шаг может быть только равным числу кратному степени 2 и не равен нулю.
(1, 2, 4, 8, 16 ...)
База задаёт лишь смещение значений индексного регистра.
*
h3. 3) Рассмотрим модификацию индексного регистра на примерах* примерах
а) Пусть необходим счётчик на 10000 итераций с шагом 1.
<pre>
N = 10000, L = 1;
Найдём значения I, M, B
1) I = (K-N+1)*L = (16384-10000+1)*1 = 6385
К выбиралось как ближайшее к N число кратное степени 2,
т.е. 2^14 - 16384
2) M = (K-1)*L = (16384-1)*1 = 16383
3) B = 0
</pre>
Индексный регистр номер 32 будет изменяться от 6385 до 16383, после
16383 индексный регистр примет значение 0. В результате изменения регистра
от 6385 до 0 мы получим 10000 итераций с шагом изменения 1 по завершению параграфа.
Если задать значение базы, например B = 4, то индексный регистр 32 будет
изменяться от 6389 до 16387, причём следующее значение после 16387 будет 4.
Пример на ассемблере с модификацией индексного регистра будет выглядеть следующим
образом:
<pre>
set_modr:
getl (6385<<16)|16383 //заполняем индекс и маску
patch @1, 0 //склеиваем маску индекс и базу в 64 разряда
setq #32, @1 //записываем значение в регистр
setl #MODR, 1 //разрешаем модификацию первого индексного регистра
jmp paragraph64
complete
paragraph64:
exa #32 //получаем значение индекс + база
je @1, part2 //условный переход, проверка на ноль
jne @2, paragraph64
complete
</pre>
б) Пусть необходим счётчик на 5300 итераций с шагом 4.
<pre>
N = 5300, L = 4;
Найдём значения I, M, B
1) I = (K-N+1)*L = (8192-5300+1)*4 = 11572
К выбиралось как ближайшее к N число кратное степени 2,
т.е. 2^13 - 8192
2) M = (K-1)*L = (8192-1)*4 = 32764
3) B = 0
</pre>
Индексный регистр номер 32 будет изменяться от 11572 до 32764, после
32764 индексный регистр примет значение 0. В результате изменения регистра
от 11572 до 0 мы получим 5300 итераций с шагом изменения 4 по завершению параграфа.
Если задать значение базы, например B = 6, то индексный регистр 32 будет
изменяться от 11578 до 32780, причём следующее значение после 32780 будет 6.
Пример на ассемблере с модификацией индексного регистра будет выглядеть следующим
образом:
<pre>
set_modr:
getl (11572<<16)|32764 //заполняем индекс и маску
patch @1, 0 //склеиваем маску индекс и базу в 64 разряда
setq #32, @1 //записываем значение в регистр
setl #MODR, 1 //разрешаем модификацию первого индексного регистра
jmp paragraph64
complete
paragraph64:
exa #32 //получаем значение индекс + база
je @1, part2 //условный переход, проверка на ноль
jne @2, paragraph64
complete
</pre>