Из сборника Введение в информатику. Лабораторные работы. Ч. II / Авт.-сост. А.П. Шестаков; Перм. ун-т. — Пермь, 1999. — 71 с.

Другие возможности E97: работа с короткой константой, текстом, логическими выражениями, управление стеком

Удобным способом выполнения действия с константой, значение которой не превышает по абсолютной величине 15(10) (F(16)), является операция с короткой константой. В этом случае место первого операнда (ОП1) в двухадресной команде занимает модуль константы. На знак константы указывает модификатор. Если его значение 2(16), то константа положительная; 3(16) — отрицательная. Указанный способ оказывается экономичнее рассмотренного ранее способа адресации по PC, т.к. команда в этом случае занимает одно слово вместо двух.

Например, команда "переслать по адресу, записанному в регистре R0, число 3"

0020 01D4
0022 0003
может быть заменена на такую 0020 2134, которая выполняет то же самое действие.

Решим задачу из данной лабораторной работы с использованием того же алгоритма и с тем же распределением памяти, только вместо адресации по PC, где возможно, будем использовать действие с короткой константой.

Пример. Поменять местами первый отрицательный элемент массива и его максимальный элемент.

Программа

Адрес Команда  Действие                                 Замечания
0000	2125	2 => (R1)				i := 2
0002	0103	R0 => R3				адрес максимального элемента
0004	2221	R1 := R1 + 2				адрес otr
0006	2105	0 => (R1)				otr := 0
0008	2404	сравнить a[1] с 0			(R0) - 0
000A	2D04	если a[1]>=0, переход на 4 байта
000C	0106	R0 => (R2)				адрес 1-го отриц. элемента
000E	2115	1 => (R1)				otr := 1
0010	2222	R2 := R2 + 2				адрес n
0012	2321	R1 := R1 - 2				адрес i
0014	2220	R0 := R0 + 2				адрес 2-го элемента массива
0016	0456	сравнить (R1) с (R2) (i с n)		(R2) - (R1)
0018	3D20	если <0, переход на 20 байт		переход на обмен значений
001A	2221	R1 := R1 + 2				адрес otr
001C	2404	сравнить (R0) c 0			(R0) - 0
001E	2D0C	если >= 0, переход на C байт
0020	2405	сравнить (R1) c 0			(R1) - 0
0022	4D08	если <>0, переход на 8 байт
0024	2322	R2 := R2 - 2				адрес k
0026	0106	R0 => (R2)				адрес 1-го отриц. элемента
0028	2115	1 => (R1)				otr := 1
002A	2222	R2 := R2 + 2				адрес n
002C	0447	ср. (R0) с (R3) (a[i] c a[max])		(R3) - (R0)
002E	2D02	если >=0, переход на 2 байта		если a[max]>=a[i]
0030	0103	R0 => R3				адрес максимального элемента
0032	2321	R1 := R1 - 2				адрес i
0034	2215	(R1) := (R1) + 1			i:= i + 1
0036	2220	R0 := R0 + 2				адрес i-го элемента
0038	1DDC	переход на -24 байт		на сравнение i с n
003A	2322	R2 := R2 - 2				адрес k
003C	0162	(R2) => R2
003E	0161	(R2) => R1				vsp := a[k]
0040	0176	(R3) => (R2)				a[k] := a[max]
0042	0117	R1 => (R3)				a[max] := a[k]
0044	0F00	стоп

Как видно, в этом случае программа значительно сократилась.

Автор E97 реализовал достаточно много полезных подпрограмм, которые размещаются в ПЗУ. Напомним, что ПЗУ начинается с адреса 4000(16). Среди этих программ особо стоит выделить те, которые позволяют работать с клавиатурой и дисплеем, т.е. организовывать ввод-вывод данных.

Перечислим их.

  1. Вывод целого числа (подпрограмма WriteInteger). Адрес начала — 4068. В R1 — выводимое число, в R3 — адрес области памяти, свободной от программы и данных (организация буфера — для хранения промежуточных значений). Содержимое регистров R0-R3 сохраняется.
  2. Вывод строки на дисплей (подпрограмма WriteString). Адрес начала — 4078. В R2 — количество символов в выводимой строке, в R3 — адрес начала строки. Содержимое регистров R0, R1 сохраняется, R2, R3 — нет.
  3. Вывод символа на дисплей (подпрограмма OutSym). Адрес начала — 4088. В R0 — выводимый символ. Содержимое R0-R3 сохраняется.
  4. Ввод символа с эхо-печатью (подпрограмма InSymE). Адрес начала — 40FA. В R0 — вводимый символ, содержимое регистров R1-R3 сохраняется.
  5. Ввод целого числа (подпрограмма Input_Integer). Адрес начала — 4108. В R1 — введенное число, все другие регистры сохраняются.
  6. Вывод логического значения (подпрограмма WriteBoolean). Адрес начала — 40C4. При R1 = 0 выводится FALSE, иначе — TRUE. В R1 — значение. R0, R1 сохраняются, R2, R3 — нет.
  7. Вывод текста, находящегося после вызова подпрограммы (п/п WritePasString). Адрес начала — 40DC. R0, R1 — сохраняются, R2, R3 — нет.
  8. Вывод целого числа (второй вариант подпрограммы, описание отсутствует в авторском изложении E97 — п/п NewWriteInteger). Адрес начала — 4152. В R1 — выводимое число; R0 = 0 — выравнивание выводимого числа по левому краю, во всех других случаях — по правому. Содержимое регистров R0-R3 сохраняется.

Рассмотрим пример, где организуется ввод данных с клавиатуры и результат выводится на экран.

Пример. Вычислить значение выражения u=x3y-y2z+12xyz, организовав ввод данных с клавиатуры и вывод результатов на экран.

При решении необходимо позаботиться о распределении памяти с оглядкой на то, что некоторые регистры, а также часть ОЗУ используется подпрограммами ввода-вывода.

План решения

1. Ввод x, y, z.	6. S := yz.
2. P := x2.		7. R := R - S.
3. R := 12z.		8. U := yR.
4. R := P + R.		9. Вывод U.
5. R := Rx.		10. Стоп.

Распределение памяти. Значения x, y, z после ввода разместим в памяти по последовательным адресам 80-84(16). Регистры R1, R2 будем использовать для хранения величин P, R, S. Значение U получим в R1. Кроме того, некоторые регистры будут использованы стандартными подпрограммами (см. выше). Указатель стека установим для удобства на последний адрес ОЗУ — FE(16).

Тесты

  1. x=1, y=2, z=3; u=62.
  2. x=-1, y=-2, z=-3; u=-58.

Программа

Адрес Команда  Действие                                 Замечания
0000	0E6D	FE => SP				установка SP
0002	00FE
0004	01D0	80 => R0				адрес x
0006	0080
0008	9C0D	вызов п/п    
000A	40DC	вывода текста
000C	7802	текст "x?"				2 - длина текста
000E	003F
0010	9C0D	вызов п/п
0012	4108	ввода целого числа
0014	0114	R1 => (R0)				сохраняем x
0016	2220	R0 := R0 + 2				адрес y
0018	9C0D	вызов п/п    
001A	40DC	вывода текста
001C	7902	текст "y?"				2 - длина текста
001E	003F
0020	9C0D	вызов п/п
0022	4108	ввода целого числа
0024	0114	R1 => (R0)				сохраняем y
0026	2220	R0 := R0 + 2				адрес z
0028	9C0D	вызов п/п    
002A	40DC	вывода текста
002C	7A02	текст "z?"				2 - длина текста
002E	003F
0030	9C0D	вызов п/п
0032	4108	ввода целого числа
0034	0114	R1 => (R0)				сохраняем z
0036	3240	R0 := R0 - 4				адрес x
0038	0142	(R0) => R2				x => R2
003A	0522	R2 := R2 * R2				P := x2
003C	2240	R0 := R0 + 4				адрес z
003E	0141	(R0) => R1				z => R1
0040	25C1	R1 := R1 * 12				R := 12z
0042	0221	R1 := R1 + R2				R := R + P
0044	3240	R0 := R0 + (-4)				адрес x
0046	0541	R1 := R1 * (R0)				R := Rx
0048	2220	R0 := R0 + 2				адрес y
004A	0142	(R0) => R2
004C	2220	R0 := R0 + 2				адрес z
004E	0542	R2 := R2 * (R0)				S := yz
0050	0321	R1 := R1 - R2				R := R - S
0052	3220	R0 := R0 + (-2)				адрес y
0054	0541	R1 := R1 * (R0)				U := Ry
0056	9C0D	вызов п/п    
0058	40DC	вывода текста
005A	7502	текст "u="				2 - длина текста
005C	003D
005E	01D3	в R3 помещаем				используется
0060	0090	адрес 90				в п/п
0062	9C0D	п/п вывода
0064	4068	целого числа
0066	0F00	стоп

В E97 используются команды для работы не только с машинными словами, но и отдельными байтами. Рассмотрим некоторые из них на примере программы обработки текста.

Пример. Составить программу, которая определяет количество заглавных русских букв в заданном тексте и выводит результат на экран.

Пусть текст находится в ОЗУ. Будем считать, что текст закончился, если встретится код 00(16). Примем во внимание, что диапазон кодов заглавных русских букв 80(16)-9F(16).

План решения

1. S := 0.
2. Сравнить код символа с 00(16).
3. Если равен, переход к п. 7.
4. Если код символа больше 7F(16), но меньше A0(16), то S := S + 1.
5. Перейти к следующему символу.
6. Переход к п. 2.
7. Вывод S.
8. Стоп.

Распределение памяти
R0 R1 R2 R3
адрес символа S  —  —

Тест. Текст: НА ШАХМАТНОЙ доске 64 КЛЕТКИ. S = 17.

Программа

Адрес Команда  Действие                                 Замечания
0000	2101	0 => R1					S := 0
0002	C44D	сравнить (R0)b				не встретили ли
0004	0000	с (0)b					символ с кодом 0
0006	5D12	если =0, переход на 12(16) байт
0008	C44D	сравнить (R0)b с (7F)b			7F - (R0)
000A	007F
000C	2D08	если >=0, переход на 8(16) байт
000E	C44D	сравнить (R0)b с (A0)b			A0 - (R0)
0010	00A0
0012	6D02	если <=0, переход на 2(16) байта
0014	2211	R1 := R1 + 1				S := S + 1
0016	2210	R0 := R0 + 1				к следующему символу
0018	1DE8	переход к адресу 0002
001A	0111
001C	9C0D	вызов п/п                 
001E	40DC	вывода последующего текста
0020	AE06	текст из 6 символов
0022	A2E2	"ответ:"
0024	E2A5
0026	003A
0028	01D3	в R3 помещаем				используется
002A	0090	адрес 90				в п/п
002C	9C0D	п/п вывода
002E	4068	целого числа
0030	0F00	стоп

Следующий пример иллюстрирует работу с логическими выражениями, командами Е97, выполняющими логические операции.

Пример. Построить таблицу истинности для логического выражения (A or B) and C. Результаты вывести на экран.

Для решения задачи организуем цикл по каждой из переменных A, B, C. Результат обозначим D. Для дальнейших действие закодируем значение ИСТИНА (TRUE) с помощью числа -1 (FFFF), ЛОЖЬ (FALSE) — с помощью числа 0 (0000) (такой способ кодирования применяется, например, в языке BASIC). Для простоты будем хранить логическое значение не с помощью одного байта, как это реализовано в тех или иных языках программирования, а займем под него машинное слово. Получив очередное значение D, будем печатать A, B, C, D.

План решения

1. A := -1.				11. D := K and C.
2. Сравнить A с 0.			12. Вывод A, B, C, D.
3. Если A > 0, переход к п. 19.		13. C := C + 1.
4. B := -1.				14. переход к п. 9.
5. Сравнить B с 0.			15. B := B + 1.
6. Если B > 0, переход к п. 17.		16. переход к п. 4.
7. K := A or B.				17. A := A + 1.
8. C := -1.				18. переход к п. 2.
9. Сравнить C с 0.			19. Стоп.
10. Если C > 0, переход к п. 15.

Распределение памяти. В регистр R0 поместим адрес переменных A, B, C (перед запуском программы зададим там адрес величины A). В регистре R1 — величина D; R2 — K. Кроме того, регистры используются стандартными подпрограммами; перед переходом на подпрограммы будем сохранять содержимое регистров в стеке, восстанавливая его в последствии.

Результатом работы программы будет следующая таблица

A	B	C	D
TRUE	TRUE	TRUE	TRUE
TRUE	TRUE	FALSE	FALSE
TRUE	FALSE	TRUE	TRUE
TRUE	FALSE	FALSE	FALSE
FALSE	TRUE	TRUE	TRUE
FALSE	TRUE	FALSE	FALSE
FALSE	FALSE	TRUE	FALSE
FALSE	FALSE	FALSE	FALSE

Программа

Адрес Команда  Действие                                 Замечания
0000	0E6D	FE => SP				установка SP
0002	00FE
0004	01D4	-1 => (R0)				A := -1
0006	FFFF
0008	2404	сравнить (R0) с 0			(A - 0)
000A	7D56	если >0, переход на стоп
000C	2220	R0 + 2 => R0				адрес B
000E	01D4	-1=> (R0)				B := -1
0010	FFFF
0012	2404	сравнить (R0) с 0			(B - 0)
0014	7D46	если >0, переход на A:=A+1
0016	0142	(R0) => R2				B => R2
0018	3220	R0 -2=> R0				адрес A
001A	0842	(R0) or R2 => R2			K := A or B
001C	2240	R0 + 4 => R0				адрес C
001E	01D4	-1=> (R0)				C := -1
0020	FFFF
0022	2404	сравнить (R0) с 0			(C - 0)
0024	7D30	если >0, переход на B:=B+1
0026	0141	(R0) => R1				C => R2
0028	0721	R2 and R1 => R1				D := K and C
002A	0E22	R2 => стек				K => стек
002C	0E21	R1 => стек				D => стек
002E	3240	R0 - 4 => R0				адрес A
0030	0141	(R0) => R1				A => R1
0032	9C0D	п/п вывода значения
0034	0090	логической константы
0036	2220	R0 + 2 => R0				адрес B
0038	0141	(R0) => R1				B => R1
003A	9C0D	п/п вывода значения
003C	0090	логической константы
003E	2220	R0 + 2 => R0				адрес C
0040	0141	(R0) => R1				C => R1
0042	9C0D	п/п вывода значения
0044	0090	логической константы
0046	0E31	стек => R1				D => R1
0048	9C0D	п/п вывода значения
004A	0090	логической константы
004C	9C0D	п/п перевода строки
004E	40EC
0050	0E32	стек => R2				K => R2
0052	2214	(R0) + 1 => (R0)			C := C + 1
0054	1DCC	переход к сравнению C с 0
0056	3220	R0 -2=> R0				адрес B
0058	2214	(R0) + 1 => (R0)			B := B + 1
005A	1DB6	переход к сравнению B с 0
005C	3220	R0 -2=> R0				адрес A
005E	2214	(R0) + 1 => (R0)			A := A + 1
0060	1DA6	переход к сравнению A с 0
0062	0F00	стоп

С адреса 0090 разместим измененный вариант авторской подпрограммы вывода значения логической константы. Изменения связаны с тем, что, во-первых, рассмотренной программе логическая константа кодируется 2 байтами, во-вторых, для получения таблицы в подпрограмме выводятся в каждом случае 6 символов: TRUE дополняется двумя пробелами, FALSE — одним.

Адрес Команда  Действие                                 Замечания
0090	2401	сравнить R1 c 0				R1 - 0
0092	5D0E	если 0, переход к выводу FALSE
0094	9C0D	п/п вывода            
0096	40DC	следующего далее текста
0098	5406	количество символов — 6;
009A	5552	текст TRUE
009C	2045
009E	0020
00A0	1D0C	переход к возврату из п/п
00A2	9C0D	п/п вывода            
00A4	40DC	следующего далее текста
00A6	4606	количество символов — 6;
00A8	4C41	текст FALSE
00AA	4553
00AC	0020
00AE	0D00	возврат из п/п

В нескольких предыдущих программах были использованы одноадресные команды. В этом случае код операции есть E, и поскольку операнд всего один, то место одного из операндов (в двухадресных командах это ОП1) занимает дополнительный код операции. За счет этого появляется 12 одноадресных команд. Например, были использованы команды E2 (пересылка операнда в стек), E3 (возвращение операнда из стека), E6 (помещение операнда в регистр SP — установка указателя стека). Полный список команд представлен в руководстве от автора E97.

Задания для самостоятельного выполнения



I. Ввести значения переменных с клавиатуры, вычислить значение выражения и результат вывести на экран:



II. Задания на обработку текста.

  1. Подсчитать количество русских букв в данном тексте.
  2. Подсчитать количество вхождений заданной буквы в данном тексте.
  3. Подсчитать число слов в строке. Слова отделяются друг от друга ровно одним пробелом.
  4. Определить, является ли данный текст числом, записанным в десятичной системе счисления, т.е. состоит только из арабских цифр от 0 до 9.
  5. Удалить из данной строки любой требуемый введенный с клавиатуры символ.
  6. Удаляющую все лишние пробелы из данной строки, т.е оставить между словами не более одного пробела.
  7. Определить длину самого короткого слова в заданном тексте.
  8. Замените в заданном слове все буквы "о" пробелами.
  9. В тексте, состоящем из латинских букв и заканчивающемся точкой, подсчитайте количество гласных букв.
  10. Дано слово. Перевернуть его.
  11. Заданы фамилия, имя и отчество учащегося, разделенные пробелами. Оставить только фамилию и инициалы.
  12. Вычеркнуть i-ю букву заданного слова.
  13. Вычеркнуть из заданного слова все буквы, совпадающие с его последней буквой.
  14. Вычеркнуть из слова X те буквы, которые встречаются в слове Z.
  15. Составить программу перевода строки строчных русских букв в прописные.
  16. Составить программу, вычеркивающую каждую третью букву заданного слова.
  17. Составить программу, выясняющую, на гласную или согласную букву оканчивается заданное русское слово.
  18. Дана строка. Подсчитать в ней количество вхождений букв r, k, t.
  19. Дана строка. Определить, сколько в ней знаков * ; :.
  20. Дана строка, среди символов которой есть двоеточие (:). Определить, сколько символов ему предшествует.
  21. Дана строка. Подсчитать самую длинную последовательность подряд идущих букв a.
  22. Дана строка, среди символов которой есть одна открывающаяся и одна закрывающаяся скобка. Вывести на экран все символы, расположенные внутри этих скобок.
  23. Имеется строка, содержащая буквы латинского алфавита и цифры. Вывести на экран длину наибольшей последовательности цифр, идущих подряд.
  24. В строке заменить все двоеточия (:) точкой с запятой (;). Подсчитать количество замен.
  25. Строка содержит одно слово. Проверить, будет ли оно читаться одинаково справа налево и слева направо (т.е. является ли оно палиндромом).


III. Составить программу, которая позволят построить таблицу истинности для заданного логического выражения и вывести ее на экран. Проверить результаты работы программы с помощью составления таблицы истинности. Примечание. Логическое значение ИСТИНА (TRUE) можно закодировать кодом FFFF, а ЛОЖЬ (FALSE) — кодом 0000. Возможны и другие варианты кодировки.

1. (X and Y) or (Z and X)		 9. (X or Y) and not Z
2. not(X or Y or Z)			10. not(X or Y) and Z
3. X and (not Y or Z)			11. X or not(Y and Z)
4. not(X and Y) or Z			12. not(X and Y or Z)
5. not(X and Y and Z)			13. not X and Y and Z
6. X and not Y and Z			14. X or not Y or Z
7. (X and Y) or not Z			15. (X and Z) or not Y
8. (X and Z) or (Y and Z)		16. (X and Y) xor (X and Z)

17. (X xor Y) or (X xor Z)		24. not X and (Y or Z)
18. not(X xor Y xor Z)			25. X xor Y and not Z
19. not X xor Y xor Z			26. X and not Y xor Z
20. (X or Y) xor not Z			27. X or not(Y xor Z)
21. X or Y or (X xor Z)			28. not X and (Y xor Z)
22. (X xor Y) or (Z and Z)		29. X xor (not Y or Z)
23. X and not(Y and Z)			30. X or  not(Y xor Z)

 


Рейтинг ресурсов УралWeb
© А.П. Шестаков, 1999-2010
Сайт создан в системе uCoz