4.5. ПРИМЕРЫ ПРОГРАММ

К оглавлению1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 
17 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                 «Т»