4.5. ПРИМЕРЫ ПРОГРАММ
К оглавлению1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1617 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
Пример 1. Вычислить полную поверхность параллелепипеда со сторонами А, В и С. Считать, что исходные значения находятся в ячейках ОЗУ. Результат также поместить в ячейку памяти.
Решение. Полная поверхность параллелепипеда вычисляется по формуле
S=2*(A*B+A*C+B*C)
Для упрощения программы выражение удобно представить в виде S = 2 * [А * (В + С) + В * С]
Программа 134
0000 01ЕО (22) => R0 В => R0
0002 0022
0004 0101 R0 => Rl В => Rl
0006 02Е0 R0 + (24) => R0 В + С
0008 0024
000А 05Е0 R0 * (20) => R0 A * (В + С)
000С 0020
000Е 05Е1 Rl * (24) => Rl В * С
0010 0024
0012 0210 R0 + Rl => R0 A * (В + С) + В * С
0014 0200 R0 + R0 => R0 2 * [A * (В + С) + В * С]
0016 010Е R0 => (26) результат => S
0018 0026
001A 0F00 останов
……….
0020 0002 А
0022 0003 В
0024 0004 С
0026 0034 S
Примечание. Не забывайте, что ответ 34 в памяти ЭВМ представлен в шестнадцатеричной системе. В десятичной, как и положено, получится 52.
Пример 2. Организовать ввод латинских букв таким образом: программа принимает латинскую букву и обрабатывает ее так, чтобы она всегда была заглавной.
Решение. Главная «хитрость» решения состоит в том, чтобы понять, чем отличаются заглавные буквы от строчных. Для этого из таблицы ASCII, приведенной в главе 1, выберем наугад одну из букв и выпишем в двоичном виде коды заглавного и строчного символов. Например, для буквы R получим
R 0101 0010
r 0111 0010
Повторив аналогичные действия еще для нескольких букв, сделаем вывод, что коды заглавных ч строчных букв отличаются единственным битом - пятым, если считать младший бит за нулевой. Запомним этот факт, поскольку он справедлив для любого современного компьютера.
Итак, для нашей задачи требуется сохранить все биты, кроме пятого, значит потребуется выполнить логическую операцию И с константой
1101 1111 =DF,
после чего любой код «потеряет» ненужный нам бит, сохраняя все остальные.
Еще одной особенностью решения является активное использование подпрограмм из ПЗУ. Поскольку при вызове подпрограмм обязательно используется стековая память, то должен быть корректно определен указатель стека SP; программа начинает работу с установки указателя стека.
Программа 135
0000 0E6D 26 => SP установка указателя стека
0002 0026
0004 9C0D вызов п/п 40FE ввод символа (без эхо-печати!)
0006 40FE
0008 0101 R0 => Rl сохранить введенный символ
000A 07D0 DF and R0 => R0 сделать букву заглавной
000C 00DF
000E 9C0D вызов п/п 4088 вывести результат
0010 4088
0012 0F00 останов
Пример 3. Найти максимум из трех чисел, находящихся в регистрах Rl, R2 и R3. Переписать наибольшее из них в R0.
Решение. Сначала максимальное из чисел в Rl и R2 занесем в R0. После этого, если R3 окажется больше R0, «исправим положение», переписав в качестве ответа R3.
Программа 136
0000 0412 сравнить R2 с Rl
0002 3D04 если < 0, то РС=РС+4 к записи Rl (к 0008)
0004 0120 R2 => R0 запомнить R2
0006 1D02 РС=РС+2 обход второй ветви (к 000A)
0008 0110 Rl => R0 запомнить Rl
000A 0403 сравнить R3 с R0
000C 3D02 если < 0, то РC=РС+2 к выходу (к 0010)
000E 0130 R3 => R0 запомнить R3
0010 0F00 останов
Пример 4. Найти сумму первых 100 натуральных чисел.
Говорят, такую задачу некогда решил в уме юный Гаусс, когда учился в школе. Мы будем решать задачу «в лоб», т.е. честно суммировть с помощью компьютера. Решение. Поместим в R3 обрабатываемое в данный момент число N (меняется от 1 до 100), а в R0 - результирующую сумму S. Зададим им начальные значения и будем циклически добавлять к S текущее значение N. Признаком окончания цикла будет ситуация, когда N > 100.
Программа 137
0000 2113 1 => R3 1 => N
0002 2100 0 => R0 0 => S
0С04 0230 R0 + R3 => R0 S = S + N
0006 2213 R3 + 1 => R3 N=N+1
0008 04D3 сравнить R3 с 100 сравнить N и 100
000A 0064
000C 6DF6 если ≤0, то PC=PC+F6 если N≤100,
к повторению (000E + FFF6 = 0004)
000E 0F00 останов
Пример 5. Вывести на экран весь латинский алфавит от А до Z. Решение. Разместим в RO выводимый латинский символ, первоначальное значение которого будет «А» (код 65 = 41h). Вывод будем осуществлять обращением к соответствующей подпрограмме ПЗУ. Для перехода к следующему символу алфавита достаточно прибавить 1 к коду текущего символа (очень похоже на переход к следующему числу в предыдущем примере). Остается только проверить, не выходит ли вновь полученный символ за латинский алфавит, т.е. не превышает ли его код 5Ah («Z»), и, если ответ будет «да» (превышает), то закончить процедуру.
Программа 138
0000 0E6D 26 => SP установка указателя стека
0002 0026
0004 01D0 41 => R0 код первого символа
0006 0041 («А»)
0008 9C0D вызов п/п 4088 вывод символа
000А 4088
000С 2210 R0 + 1 => R0 следующий символ
000Е 04D0 сравнить R0 с 5А его код ≤ «Z»?
0010 005А («Z»)
0012 6DF4 если ≤0, то PC=PC+F4 к повторению (0008)
0014 0F00 останов
Пример 6. В памяти, начиная с адреса 001А, хранится некоторый текст, длина которого равна 15 (Fh) байтам Определить номер первого, совпадающего с образцом, символа в тексте. При отсутствии требуемого символа результат равен 0 (это практически полный аналог функции POS в Паскале).
Решение Поместим в R1 счетчик символов, в R2 - адрес текущего символа. Затем будем сравнивать каждый символ текста с образцом в R0 и в случае совпадения прервем выполнение цикла. При несовпадении будем продолжать цикл до теx пор, пока счетчик не превысит Fh, т.е. не станет равным 10h Если цикл завершится по выполнении этого условия, то символ-образец найти не удалось и в качестве ответа в R1 следует занести 0.
Программа 139
0000 2111 1 => R1 номер символа
0002 01D2 1А => R2 адрес начала текста
0004 001А
0006 С460 сравнить R0b с (R2)b сравнить символ с образцом
0008 5D0C если = 0, то РC=РС+2 выход при совпадении (к 0016)
000А 2211 R1 + 1 => R1 увеличить номер символа
000С 2212 R2 + 1 => R2 вычислить следующий адрес
000Е 04D1 сравнить R1 с 10 текст не закончился?
0010 0010
0012 4DF2 если ≠ 0, то PC=PC+F4 нет - к повторению (к 0006)
0014 2101 0 => R1 при отсутствии символа - 0
0016 0F00 останов
0018 0000
001А 4854 «ТН» текст
001С 5349 «IS» «THIS IS MY TEXT»
001E 4920 «I»
0020 2053 «S »
0022 594D «MY»
0024 5420 «Т»
0026 5845 «EX»
0028 0054 «Т»
Пример 1. Вычислить полную поверхность параллелепипеда со сторонами А, В и С. Считать, что исходные значения находятся в ячейках ОЗУ. Результат также поместить в ячейку памяти.
Решение. Полная поверхность параллелепипеда вычисляется по формуле
S=2*(A*B+A*C+B*C)
Для упрощения программы выражение удобно представить в виде S = 2 * [А * (В + С) + В * С]
Программа 134
0000 01ЕО (22) => R0 В => R0
0002 0022
0004 0101 R0 => Rl В => Rl
0006 02Е0 R0 + (24) => R0 В + С
0008 0024
000А 05Е0 R0 * (20) => R0 A * (В + С)
000С 0020
000Е 05Е1 Rl * (24) => Rl В * С
0010 0024
0012 0210 R0 + Rl => R0 A * (В + С) + В * С
0014 0200 R0 + R0 => R0 2 * [A * (В + С) + В * С]
0016 010Е R0 => (26) результат => S
0018 0026
001A 0F00 останов
……….
0020 0002 А
0022 0003 В
0024 0004 С
0026 0034 S
Примечание. Не забывайте, что ответ 34 в памяти ЭВМ представлен в шестнадцатеричной системе. В десятичной, как и положено, получится 52.
Пример 2. Организовать ввод латинских букв таким образом: программа принимает латинскую букву и обрабатывает ее так, чтобы она всегда была заглавной.
Решение. Главная «хитрость» решения состоит в том, чтобы понять, чем отличаются заглавные буквы от строчных. Для этого из таблицы ASCII, приведенной в главе 1, выберем наугад одну из букв и выпишем в двоичном виде коды заглавного и строчного символов. Например, для буквы R получим
R 0101 0010
r 0111 0010
Повторив аналогичные действия еще для нескольких букв, сделаем вывод, что коды заглавных ч строчных букв отличаются единственным битом - пятым, если считать младший бит за нулевой. Запомним этот факт, поскольку он справедлив для любого современного компьютера.
Итак, для нашей задачи требуется сохранить все биты, кроме пятого, значит потребуется выполнить логическую операцию И с константой
1101 1111 =DF,
после чего любой код «потеряет» ненужный нам бит, сохраняя все остальные.
Еще одной особенностью решения является активное использование подпрограмм из ПЗУ. Поскольку при вызове подпрограмм обязательно используется стековая память, то должен быть корректно определен указатель стека SP; программа начинает работу с установки указателя стека.
Программа 135
0000 0E6D 26 => SP установка указателя стека
0002 0026
0004 9C0D вызов п/п 40FE ввод символа (без эхо-печати!)
0006 40FE
0008 0101 R0 => Rl сохранить введенный символ
000A 07D0 DF and R0 => R0 сделать букву заглавной
000C 00DF
000E 9C0D вызов п/п 4088 вывести результат
0010 4088
0012 0F00 останов
Пример 3. Найти максимум из трех чисел, находящихся в регистрах Rl, R2 и R3. Переписать наибольшее из них в R0.
Решение. Сначала максимальное из чисел в Rl и R2 занесем в R0. После этого, если R3 окажется больше R0, «исправим положение», переписав в качестве ответа R3.
Программа 136
0000 0412 сравнить R2 с Rl
0002 3D04 если < 0, то РС=РС+4 к записи Rl (к 0008)
0004 0120 R2 => R0 запомнить R2
0006 1D02 РС=РС+2 обход второй ветви (к 000A)
0008 0110 Rl => R0 запомнить Rl
000A 0403 сравнить R3 с R0
000C 3D02 если < 0, то РC=РС+2 к выходу (к 0010)
000E 0130 R3 => R0 запомнить R3
0010 0F00 останов
Пример 4. Найти сумму первых 100 натуральных чисел.
Говорят, такую задачу некогда решил в уме юный Гаусс, когда учился в школе. Мы будем решать задачу «в лоб», т.е. честно суммировть с помощью компьютера. Решение. Поместим в R3 обрабатываемое в данный момент число N (меняется от 1 до 100), а в R0 - результирующую сумму S. Зададим им начальные значения и будем циклически добавлять к S текущее значение N. Признаком окончания цикла будет ситуация, когда N > 100.
Программа 137
0000 2113 1 => R3 1 => N
0002 2100 0 => R0 0 => S
0С04 0230 R0 + R3 => R0 S = S + N
0006 2213 R3 + 1 => R3 N=N+1
0008 04D3 сравнить R3 с 100 сравнить N и 100
000A 0064
000C 6DF6 если ≤0, то PC=PC+F6 если N≤100,
к повторению (000E + FFF6 = 0004)
000E 0F00 останов
Пример 5. Вывести на экран весь латинский алфавит от А до Z. Решение. Разместим в RO выводимый латинский символ, первоначальное значение которого будет «А» (код 65 = 41h). Вывод будем осуществлять обращением к соответствующей подпрограмме ПЗУ. Для перехода к следующему символу алфавита достаточно прибавить 1 к коду текущего символа (очень похоже на переход к следующему числу в предыдущем примере). Остается только проверить, не выходит ли вновь полученный символ за латинский алфавит, т.е. не превышает ли его код 5Ah («Z»), и, если ответ будет «да» (превышает), то закончить процедуру.
Программа 138
0000 0E6D 26 => SP установка указателя стека
0002 0026
0004 01D0 41 => R0 код первого символа
0006 0041 («А»)
0008 9C0D вызов п/п 4088 вывод символа
000А 4088
000С 2210 R0 + 1 => R0 следующий символ
000Е 04D0 сравнить R0 с 5А его код ≤ «Z»?
0010 005А («Z»)
0012 6DF4 если ≤0, то PC=PC+F4 к повторению (0008)
0014 0F00 останов
Пример 6. В памяти, начиная с адреса 001А, хранится некоторый текст, длина которого равна 15 (Fh) байтам Определить номер первого, совпадающего с образцом, символа в тексте. При отсутствии требуемого символа результат равен 0 (это практически полный аналог функции POS в Паскале).
Решение Поместим в R1 счетчик символов, в R2 - адрес текущего символа. Затем будем сравнивать каждый символ текста с образцом в R0 и в случае совпадения прервем выполнение цикла. При несовпадении будем продолжать цикл до теx пор, пока счетчик не превысит Fh, т.е. не станет равным 10h Если цикл завершится по выполнении этого условия, то символ-образец найти не удалось и в качестве ответа в R1 следует занести 0.
Программа 139
0000 2111 1 => R1 номер символа
0002 01D2 1А => R2 адрес начала текста
0004 001А
0006 С460 сравнить R0b с (R2)b сравнить символ с образцом
0008 5D0C если = 0, то РC=РС+2 выход при совпадении (к 0016)
000А 2211 R1 + 1 => R1 увеличить номер символа
000С 2212 R2 + 1 => R2 вычислить следующий адрес
000Е 04D1 сравнить R1 с 10 текст не закончился?
0010 0010
0012 4DF2 если ≠ 0, то PC=PC+F4 нет - к повторению (к 0006)
0014 2101 0 => R1 при отсутствии символа - 0
0016 0F00 останов
0018 0000
001А 4854 «ТН» текст
001С 5349 «IS» «THIS IS MY TEXT»
001E 4920 «I»
0020 2053 «S »
0022 594D «MY»
0024 5420 «Т»
0026 5845 «EX»
0028 0054 «Т»