Лекции Баулы (1110628), страница 4
Текст из файла (страница 4)
Будем предполагать, что длина программы не будет превышать 200 ячеек, и разместим массив x, начиная с 200 ячейки. Переменную S с начальным значением 0.0 и переменную i с начальным значением 100 разместим в конце текста программы.
№ | Команда | Комментарий | |||
001 | ВВВ | 200 | 100 | 000 | Read(x) x в ячейках 100299 |
2 | СЛВ | 008 | 200 | 008 | S := S+x[1] |
3 | СЛЦ | 002 | 002 | 011 | модификация команды в ячейке 2 |
4 | ВЧЦ | 010 | 010 | 009 | n := n-1 |
5 | УСЛ | 006 | 006 | 002 | следующая итерация цикла |
6 | ВЫВ | 008 | 001 | 000 | Write(S) |
7 | СТОП | 000 | 000 | 000 | стоп |
8 | <0.0> | Переменная S := 0.0 | |||
9 | 00 | 000 | 000 | 001 | Целая константа 1 |
010 | 00 | 000 | 000 | 100 | Переменная с начальным значением 100 |
1 | 00 | 000 | 001 | 000 | Константа переадресации |
Рассматриваемая программа выделяется своим новым приёмом программирования и может быть названа самомодифицирующейся программой. Обратим внимание на третью строку программы. Содержащаяся в ней команда изменяет исходный код программы (команду в ячейке 2) для организации цикла перебора элементов массива. Модифицируемая команда рассматривается как целое число, которое складывается со специально подобранное константой переадресации. Согласно одному из принципов фон-Неймана, числа и команды в учебной машине неотличимы друг от друга, а, значит, изменяя числовое представление команды, мы можем изменять и её суть.
У такого метода программирования есть один существенный недостаток: модификация кода программы внутри её самой может привести к путанице и вызвать появление ошибок. В нашей учебной машине это, однако, единственный способ обработки массивов. В других архитектурах ЭВМ, с которыми мы познакомимся несколько позже, есть и другие, более эффективные способы работы с массивами, поэтому метод с модификацией команд не используется.
Формальное описание учебной машины
При описании архитектуры учебной ЭВМ на естественном языке многие вопросы остались нераскрытыми. Что, например, будет после выполнения команды из ячейки 511? Какое значение после нажатия кнопки ПУСК имеют ячейки, расположенные вне введённой программы? Как представляются целые и вещественные числа? Для ответа на почти все такие вопросы мы приведём формальное описание нашей учебной машины. В качестве метаязыка мы будем использовать Турбо-Паскаль, на котором Вы работаете. Другими словами, мы напишем программу, выполнение которой моделирует работу нашей учебной машины, т.е. наша машина, по определению, работает почти так же, как и написанная нами программа на Паскале.
Ниже приведена реализация учебной машины на языке Паскаль:
program УМ_3(input, output);
const N = 511;
type Address = 0..N;
Tag = (kom, int, fl); {В машинном слове может хранится команда, целое
или вещественное число}
Komanda = packed record
KOP: 0..31;
A1, A2, A3: Address;
end;
Slovo = packed record
case Tag of
kom: (k: Komanda);
int: (i: LongInt)
fl: (f: Float);
end
Memory = array[0..N] of Slovo;
Var Mem: Memory;
S, R1, R2: Slovo; {Регистры АЛУ}
A1, A2, A3: Address;
RK: Komanda; {Регистр команд}
RA: Address; {Счётчик адреса}
Om: 0..2; {Регистр w}
Err: Boolean;
begin
Input_Program; {Эта процедура должна вводить текст программы с устройства
ввода в память}
Om := 0; Err := False; RA := 1; {Начальная установка регистров}
repeat {Основной цикл выполнения команд}
RK := Mem[RA];
RA := (RA+1) mod (N+1);
A1 := RK.A1;
A2 := RK.A2;
A3 := RK.A3;
case RK.KOP of {Анализ кода операции}
00: { ПЕР } begin R1 := Mem[A3]; Mem[A1] := R1 end;
01: { СЛВ } begin R1 := Mem[A2]; R2 := Mem[A3]; S.f := R1.f + R2.f;
if S.f = 0.0 then OM := 0 else
if S.f < 0.0 then OM := 1 else OM := 2;
Mem[A1] := S; { Err := ? }
end;
09: { БЕЗ }RA := A2;
24: { МОД }begin R1 := Mem[A2]; R2 := Mem[A3];
if R2.i = 0 then Err := True else begin
S.i := R1. mod R2.i; Mem[A1] := S;
if S.f = 0.0 then OM := 0 else
if S.f < 0.0 then OM := 1 else OM := 2;
end
end;
{ Все другие коды операции }
else
Err := True;
end; { case }
until Err or (RK.KOP = 31)
end.
Наша программа ведёт себя почти так же, как учебная машина. Одно из немногих мест, где это поведение расходится, показано в тексте программы, например, при реализации команды сложения вещественных чисел. Программа на Паскале при переполнении (когда результат сложения не помещается на регистр S) производит аварийное завершение программы, а наша учебная машина просто присваивает регистру Err значение 1. Наше формальное описание отвечает и на вопрос о том, как в учебной машине представляются целые и вещественные числа: точно так же, как в переменных на Паскале. Это представление мы изучим в нашем курсе несколько позже.
Адресность ЭВМ
Как мы помним, число адресов в команде называется адресностью ЭВМ. Разнообразие архитектур ЭВМ предполагает, в частности, и различную адресность команд. Рассмотрим схему выполнения команд с различным числом адресов операндов. Будем предполагать, что для хранения кода операции в команде отводится один байт (8 разрядов), а для хранения каждого из адресов – 3 байта (это обеспечивает объём памяти 224 ячеек). Ниже приведены форматы команд для ЭВМ различной адресности и схемы выполнения этих команд для случая бинарных операций, у которых два операнда и один результат.
-
Трёхадресная машина.
КОП | A1 | A2 | A3 | = 10 байт |
8 разрядов | 24 разряда | 24 разряда | 24 разряда |
Схема выполнения команд такой машины нам уже известна:
R1 := <A2>; R2 := <A3>; S := R1 R2; <A1> := S; { – операция}
-
Двухадресная машина.
КОП | A1 | A2 | = 7 байт |
8 разрядов | 24 разряда | 24 разряда |
Схема выполнения команд:
R1 := <A1>; R2 := <A2>; S := R1 R2; <A1> := S;
Заметим, что теперь для выполнения бинарной операции первый и второй операнды задаются явно в качестве адресов в команде, а местоположение результата операции задаётся неявно или, как говорят, по умолчанию. В рассмотренном выше случае результат операции по умолчанию помещается на место первого операнда, уничтожая его.
-
Одноадресная машина.
КОП | A1 | = 4 байта |
8 разрядов | 24 разряда |
Схема выполнения команд:
R1 := <A1>; S := S R1;
Для работы в одноадресной машине необходимы ещё две команды, которые имеют один операнд и один результат и выполняются по другим схемам. Это команда чтения числа из памяти на регистр сумматора:
СЧ A1
которая выполняется по схеме
S := <A1>
и команда записи значения из сумматора в память:
ЗП A1
которая выполняется по схеме
<A1> := S
При выполнении бинарных операций в одноадресной ЭВМ только один второй операнд задаётся в команде явно, а первый операнд и результат задаются неявно – это регистр сумматора.
-
Безадресная машина.
КОП | = 1 байт |
8 разрядов |
В отличие от других рассмотренных выше машин, безадресная машина использует при работе аппаратно реализованный в компьютере стек, для чего вводятся две дополнительные одноадресные команды: записи из памяти в стек
ВСТЕК A1
которая выполняется по схеме
R1 := <A1>; ВСТЕК(R1)
и команда чтения из стека
ИЗСТЕКА A1
которая выполняется по схеме
ИЗСТЕКА(R1); <A1> := R1
Таким образом, за исключение двух указанных выше одноадресных команд, все остальные команды являются безадресными и выполняются по схеме:
R1 := ИЗСТЕКА; R2 := ИЗСТЕКА; S := R1 R2; ВСТЕК(S)
Как видно, для безадресных команд при выполнении бинарных операций уже все аргументы (два операнда и результат) задаются неявно и располагаются в стеке. Отсюда понятно, почему часто машины этой архитектуры называются стековыми ЭВМ.
Кроме рассмотренных видов машин, существовали и другие архитектуры ЭВМ – например, четырёхадресные, в четвёртом адресе которых дополнительно хранится ещё и номер следующей выполняемой команды. Собственно, адресов может быть и больше, с помощью таких команд можно, например, реализовать функции от многих переменных.
Существуют архитектуры ЭВМ, которые различаются не только количеством адресов в команде, но и несколькими кодами операций в одной команде. Такие ЭВМ называются машинами с очень длинным командным словом (very large command word). В этих компьютерах, например, указанные команды могут реализовывать оператор присваивания вида z:=k*(x+y) по схеме:
R1 := <x>; R2 := <y>; S := R1+R2; R1 := <k>; S := S*R1; <z> := S;
В этом примере команда содержит два кода операции (+ и *) и четыре адреса аргументов.
Сравнительный анализ ЭВМ различной адресности
При изучении ЭВМ с разным количеством адресов естественно встаёт вопрос, какая архитектура лучше, например, даёт программы, занимающие меньше места в памяти (что было весьма актуально для первых ЭВМ). Исследуем этот вопрос, составив небольшую программу для ЭВМ с различной адресностью. В качестве такой программы возьмём оператор присваивания x := a/(a+b)2, содержащий типичный набор операций. В наших примерах мы будем использовать мнемонические коды операций и мнемонические имена для номеров ячеек памяти, в которых хранятся переменные (т.е. мы не будем производить явного распределения памяти, так как это несущественно для нашего исследования).
-
Трёхадресная машина.
СЛ | x | a | B | X := a+b |
УМН | x | x | X | X := (a+b)2 |
ДЕЛ | x | a | x | X := a/(a+b)2 |
Длина программы: 3*10 = 30 байт.
-
Двухадресная машина.
ПЕР | R | a | R := a |
СЛ | R | b | R := a+b |
УМН | R | R | R := (a+b)2 |
ПЕР | x | a | x := a; |
ДЕЛ | x | R | x := a/(a+b)2 |
Длина программы: 5*7 = 35 байт.
-
Одноадресная машина.
СЧ | A | S := a |
СЛ | B | S := a+b |
ЗП | X | x := a+b |
УМН | X | x := (a+b)2 |
ЗП | X | |
СЧ | A | S := a/(a+b)2 |
ДЕЛ | X | |
ЗП | X |
Длина программы: 8*4 = 32 байта.
-
Безадресная машина.
ВСТЕК | a | Поместить a в стек |
ВСТЕК | Дублировать вершину стека | |
ВСТЕК | b | Поместить b в стек |
СЛ | b+a – на вершине стека | |
ВСТЕК | Дублировать вершину стека | |
УМН | (a+b)2 — вместо двух последних элементов стека | |
ОБМЕН | Поменять местами два верхних элемента стека | |
ДЕЛ | a/(a+b)2 — как при умножении | |
ИЗСТЕКА | x | Запись результата из стека в x |
В данной программе использовались команды разной длины (безадресные и одноадресные). Длина программы: 3*4 + 6*1 = 18 байт.