УМ-М: Регистры и косвенная адресация

Один из способов повысить эффективность работы программы — предусмотреть небольшое количество выделенных быстродействующих ячеек памяти — регистров общего назначения

Регистровая учебная машина УМ-Р

16 регистров позволяют проводить довольно сложные вычисления без дополнительного обмена с ОП. В начале программы данные загружаются из памяти, в конце — результаты выгружаются в память.

Пример: максимум из трёх чисел (воспользуемся совместимой с УМ-Р поддерживаемой эмулятором архитектурой УМ-М)

mmm

[config]
input = 0x20,0x22,0x24
output = 0x26

[code]
      00 1 0 0020 ; 00 ; загрузка A в R1
      00 2 0 0022 ; 02 ; загрузка B в R2
      00 3 0 0024 ; 04 ; загрузка C в R3
      20 4 1      ; 06 ; R4:=R1
      25 4 2      ; 07 ; Сравнить R4 и R2
      84 0 0 000B ; 08 ; Если ≥, обойти следующую инструкцию
      20 4 2      ; 0A ; R4:=R2
      25 4 3      ; 0B ; Сравнить R4 и R3
      84 0 0 000F ; 0C ; Если ≥, обойти следующую инструкцию
      20 4 3      ; 0E ; R4:=R3
      10 4 0 0026 ; 0F ; выгрузить R4 в D
      99 0 0      ; 11 ;

[input]
32 24 22

В регистрах можно эффективно хранить границы и изменения циклов.

Пример: ввести M и N, посчитать сумму квадратов от M2+(M+1)2+…+(N-1)2+N2

mmm

[config]
input = 0x1000, 0x1002
output = 0x1004

[code]
        00 1 0 1000 ; 00; R1:=M
        00 2 0 1002 ; 02; R2:=N
        22 3 3      ; 04; R3-=R3 (обнуление)
        00 A 0 0013 ; 05; RA:=1
        25 1 2      ; 07; сравнить R1 и R2
        86 0 0 0010 ; 08; Переход если >
        20 4 1      ; 0A; R4:=R1
        23 4 1      ; 0B; R4*=R4
        21 3 4      ; 0C; R3+=R4
        21 1 A      ; 0D; R1+=RA (+=1)
        80 0 0 0007 ; 0E; продолжение цикла
        10 3 0 1004 ; 10; выгрузить R4 в S
        99 0 0      ; 12; стоп
        00 0 0 0001 ; 13; 1

[input]
5 10

Косвенная адресация. Модификация адреса

Как было ранее показано, работа с массивами данных при помощи самомодификации кода имеет серьёзные недостатки, в частности, трудность отладки неработающей программы. Переменный размер команды эти трудности только усугубляет.

Нужен механизм, позволяющий хранить адреса вне инструкций (в памяти или в регистрах) и использовать эти адреса для доступа к соответствующим ячейкам оперативной памяти. Тогда проход по массиву данных циклом будет состоять в циклическом изменении не ячейки с командой, а ячейки, хранящей адрес.

Косвенная адресация — механизм доступа к оперативной памяти, при котором в инструкции указывается не сам адрес, а место хранения этого адреса (например, регистр).

В некоторых архитектурах разрешена косвенная адресация по памяти (из ячейки памяти считывается адрес другой ячейки памяти, по которому берётся значение) и даже двойная косвенная адресация (адрес адреса!).

Очевидный недостаток косвенной адресации — усложнение такта работы машины: извлечение адреса плюс чтение значения вместо одного чтения. Косвенная адресация по «медленной» памяти вдобавок сильно замедляет такт.

Машина с модификацией адреса УМ-М

Поскольку работа с массивами данных происходит в оперативной памяти, в УМ-М косвенная адресация используется в командах вида «Регистр-Память». Второй операнд — регистр команд вида «регистр-память» — называется смещением.

Исполнительный адрес (актуальный адрес, с которым работает инструкция), — сумма поля адреса и содержимого регистра смещения.

Такт работы операции вида «КК П С АААА», где КК — код операции, П — номер регистра-приёмника, С — номер регистра-смещения, AAAA — базовый адрес в УМ-Р

  1. Считать ячейку «КК П С»
  2. Проанализировать размер инструкции
  3. Считать ещё одну ячейку «АААА»
  4. Вычислить адрес операнда, равный AAAA + содержимое регистра № С

  5. Загрузить операнд
  6. Вычислить операцию КК
  7. Результат поместить в регистр П
  8. Вычислить адрес следующей команды

Исключение: значение 0 в поле смещения означает прямую адресацию (без смещения). Регистр R0, таким образом, невозможно использовать для смещения.

Пример: Прибавить константу 0x123 к четырём (количество произвольное) ячейкам памяти, начиная с адреса 0x1000.

mmm

[config]
input = 0x1000, 0x1002, 0x1004, 0x1006
output = 0x1000, 0x1002, 0x1004, 0x1006

[code]
22 4 4      ; 00 ; обнуление регистра (вычтем R4 из R4)
00 2 4 1000 ; 01 ; загрузим R4-й элемент массива (поначалу нулевой) в R2
01 2 0 000e ; 03 ; добавим 123 к R2
10 2 4 1000 ; 05 ; запишем обратно
01 4 0 0010 ; 07 ; добавим 2 к R4
05 4 0 0012 ; 09 ; сравним с последним индексом массива
95 0 0 0001 ; 0B ; переход обратно, если не больше
99 0 0      ; 0D ;
00000123    ; 0E ; 0x123
00000002    ; 10 ; 2
00000006    ; 12 ; 6

[input]
123 234 345 456

Здесь R4 играет роль индекса массива: инструкции 00 и 10 содержат 0x1000 в качестве базового адреса, к которому при чтении и, соответственно, записи, прибавляется содержимое R4. Размер целого в УМ-М — 4 байта, т. е. две ячейки, поэтому к R4 в цикле прибавляется константа 2.

Замечание: нет никакой принципиальной разницы между выполнением:

Однако команда 00 1 0 1008 выполняется слегка по-другому, т. к. содержимое R0 не используется, и сложения не производится.

Смещение присутствует и в командах перехода УМ-М. Это позволяет вычислять и изменять адрес перехода, не модифицируя код программы.

FrBrGeorge/MyDict/speech_balloon_question.png А зачем это может быть нужно?

В других архитектурах механизмы адресации могут быть и другие:

TODO Ещё пример на косвенную адресацию?

Программирование в машинных кодах и язык ассемблера

Цель: небессмысленно выполнить произвольную программу на ЭВМ

Задача: ввести готовую программу и данные в ОЗУ, запустить программу, получить данные

Недостатки программирования в кодах

LecturesCMC/ArchitectureAssemblerProject/05_RegistersIndexing (последним исправлял пользователь FrBrGeorge 2024-07-06 20:53:48)