Учебное пособие для иностранных студентов (1110580), страница 6
Текст из файла (страница 6)
S1 := S1 * 20;
S2 := S2 div 3
end.
Данные:
00000 a
00002 b
00004 1416 (=2010)
00006 3
00008 S1
0000A S2
Значение S1 будем вычислять в регистре R1, значение S2 — в регистре R0 .
Программа:
00100 | 00 0 00000 | R0 := a |
00102 | 00 1 00002 | R1 := b |
00104 | 25 0 1 | R0 > R1? |
00105 | 96 0 0010A | R0 R1 go to 10A |
00107 | 20 2 0 | |
00108 | 20 0 1 | |
00109 | 20 1 2 | R0 R1 |
0010A | 13 1 00004 | R1 := R1 * 20 |
0010С | 10 1 00008 | S1 := R1 |
0010E | 14 0 00006 | R0 := R0 div 3 |
00110 | 10 0 0000A | S2 := R0 |
00112 | 99 0 0 | стоп |
Пример 3. Вычислить p = n!.
Напомним алгоритм:
begin p:=1; k:=2;
while k n do
begin p := p * k;
k := k + 1
end
end.
Распределение памяти:
00000 1
00002 2
00004 n
00006 p
Для ускорения работы цикла будем использовать регистры R1 1, R2 n, R3 k, R4 p.
Программа:
00100 | 00 1 00000 | R1 := 1 |
00102 | 00 2 00004 | R2 := n |
00104 | 20 4 1 | p := 1 |
00105 | 00 3 00002 | k := 2 |
00107 | 25 3 2 | k n? |
00108 | 95 0 0010E | k > n, go to 0010E |
0010A | 33 4 3 | p := p * k |
0010B | 21 3 1 | k := k + 1 |
0010C | 80 0 00107 | go to 0107 |
0010E | 10 4 00006 | сохранили p |
00110 | 99 0 0 | стоп |
По сравнению с программой для УМ-2, потребовалась подготовительная работа по записи начальных значений в регистры (загрузка регистров). Однако основной цикл выглядит очень коротким, да и весь текст программы сократился (если считать длину в шестнадцатиричных разрядах, а не в ячейках).
Пример 4. Вычислить сумму элементов массива x1, ..., x20..
S = x1 + x2 +...+ x20
Алгоритм:
begin S := 0; i := 1;
repeat S := S + x[i];
i := i + 1
until i = 21
end.
Распределение памяти: | Используемые регистры: |
00000 x1 | R0 0 |
00002 x2 | R1 1 |
* * * | R2 2 |
00026 x20 | R3 21 |
00028 S | R4 i |
0002A 0 | R5 S |
0002C 1 | R6 , R7 вспомогательные |
0002E 1516 (=2110) | |
00030 2 |
Программа:
00100 | 00 0 0002A | R0 := 0 | загрузка | ||
00102 | 00 1 0002C | R1 := 1 | константных | ||
00104 | 00 2 00030 | R2 := 2 | регистров | ||
00106 | 00 3 0002E | R3 := 21 | |||
00108 | 00 6 0010D | R6 := [0010D] | |||
0010A | 20 7 6 | R7 := R6 | |||
0010B | 20 5 0 | S := 0 | |||
0010C | 20 4 1 | i := 1 | |||
0010D | 01 5 00000 | S := S + x [1] | |||
0010F | 21 6 2 | подготовка программы к обработке | |||
00110 | 10 6 0010D | следующего элемента массива | |||
00112 | 21 4 1 | i := i + 1 | |||
00113 | 25 4 3 | i = 21? | |||
00114 | 82 0 0010D | i 21, go to 0010D | |||
00116 | 10 5 00028 | сохранили S | |||
00118 | 10 7 0010D | восстановили первоначальный вариант команды 0010D | |||
0011A | 99 0 0 | стоп |
При решении данной задачи возникла проблема: как добиться того, чтобы в разные моменты работы программы к S прибавлялись различные элементы массива? По сути, требуется, чтобы во время работы программы менялся адрес второго операнда в команде 0010D: 01 5 00000 (S := S + x[1]). Мы сделали это так. Регистр R6 содержит копию команды 0010D. Когда команда 0010D выполнится, прибавим к R6 число 2 (адреса соседних элементов массива отличаются на 2) и запишем новую команду из R6 в программу по адресу 0010D. Таким образом, на следующем шаге цикла будет выполнена другая команда 0010D: 01 5 00002 (S := S + x[2]). это изменение текста программы производится командами 0010F, 00110. Команда 00118 восстанавливает первоначальный вариант команды 0010D. Если этого не сделать, после окончания работы программы команда 0010D будет содержать адрес ячейки, следующей за последним элементом массива x. При этом повторный запуск программы приведет к неверным результатам.
Мы встретились в этом примере с программой, которая изменяет свой текст во время работы. Такие программы называются самомодифицирующимися. Их применение довольно опасно из-за непредсказуемых последствий возможных ошибок в изменении команд.
П.4. Учебная машина с модификацией адресов УМ-М.
В программировании большое количество задач связано с обработкой массивов. Поэтому желательно сделать работу с массивами удобной. Решается эта проблема с помощью механизма модификации адресов. Суть этого механизма состоит в следующем. В команде кроме адреса операнда указывается регистр-модификатор. При выполнении команды процессор вычисляет сначала исполнительный адрес как сумму адреса, указанного в команде, и содержимого регистра-модификатора. Затем из ячейки с полученным адресом берется операнд. Изменив содержимое модификатора, мы заставляем процессор использовать другой адрес операнда. Подчеркнем, что действие по вычислению исполнительного адреса выполняется аппаратно, это дает преимущество в скорости по сравнению с самомодифицирующимся кодом (пример 4 из предыдущего пункта). Кроме того, текст программы остается всегда одним и тем же, так как изменение адреса получается за счет изменения содержимого регистра-модификатора. Это повышает надежность программ.
1. Описание учебной машины с модификацией адресов.
Машина УМ-М отличается от УМ-Р в следующем.
1) Объем ОП 164 ячеек.
2) Формат команд регистр-память
КОП R1 M2 А2
M2 — регистр, используемый для модификации адреса A2. Это может быть любой регистр общего назначения, кроме R0
3) При выполнении команд регистр-память процессор вычисляет исполнительный адрес по правилу
Второй операнд берется из ячейки с адресом Аисп.
Пример 1. Вычислить сумму элементов массива x1, ..., x20..