| ||
|
Комментарии к приведенному протоколу Теперь будем вносить необходимые изменения. Все требуемые действия зафиксированы в приведенном ниже протоколе, который является продолжением предыдущего. 1. “Сместим” основную часть программы, чтобы освободить два байта под новую переменную. Для этого наберем команду m 108 113 10a, которая означает задание отладчику подвинуть (по-английски: move) байты со 108-го по 113-й (эти значения мы запомнили из предыдущих экспериментов с программой). 2. Проверим, что программа действительно теперь начинается с адреса 10a (команда -u10a). 3. Далее можно было бы аналогичным образом освободить байты под команду вычитания и ввести ее, но проще набрать три последние команды заново, тем более что в команде записи результата в переменную r все равно потребовалось бы изменить адрес. Так что введем эти команды с адреса 111, а затем не забудем поменять адрес в стартовой инструкции перехода. 4. После этого командой e 106 4 0 занесем в переменную z ее числовое значение (опять-таки в обратном порядке!) и все еще раз проверим. 5. Наконец, запустим программу и убедимся в правильности получившегося результата: 3 + 7 – 4 = 6. Таким образом, поработав с простейшей программой, мы убедились в том, что замена адресов и переменных, и мест переходов при модификации программы представляет собой весьма трудоемкую работу, требующую предельного напряжения внимания (но, несмотря на все усилия, ошибки неизбежно случаются). От указанных трудностей можно избавиться, если для реализации программы в командах процессора использовать ассемблер. Главное преимущество ассемблера перед программой Debug заключается в том, что ассемблер нигде не использует конкретные адреса ОЗУ — вместо них везде указываются символические имена, которые называют идентификаторами. При трансляции текста программы ассемблер автоматически связывает идентификаторы с адресами ячеек памяти, в которых они будут располагаться. Как следствие, модификация текста программы не потребует никакого пересчета адресов, поскольку ассемблер1 при новой трансляции сам распределит их уже в соответствии с модифицированной программой. Текст нашей программы на ассемблере будет выглядеть так. jmp start x: dw 3 y: dw 7 z: dw 4 r: dw 0 start: mov ax,x add ax,y sub ax,z mov r,ax int 20 Легко видеть, что вставка двух выделенных строк — это все, что потребовалось при рассмотренной выше модификации программы. К сожалению, Debug не позволяет использовать идентификаторы, а значит, заметно уступает ассемблеру в данном вопросе. Впрочем, никто и не обещал, что данное программное средство является полноценным ассемблером. Директивы ассемблера Язык ассемблер содержит целый ряд
специальных управляющих операторов (обычно их
называют директивами), из которых Debug
поддерживает только некоторые. В частности,
команда dw 3, определяющая в памяти некоторую
константу, — одна из таких поддерживаемых
отладчиком директив. Таким образом, оказывается, что Debug не является в полном смысле слова ассемблирующей программой, хотя и позволяет вводить ассемблерные мнемоники команд. Следовательно, работая в Debug, мы не реализуем всех возможностей, которыми обладает настоящий язык ассемблер. В заключение заметим, что хорошее понятие об ассемблере дают учебники [2–5], где описываются учебные ЭВМ “Малютка” и “Нейман” (в книгах [3, 5] изложение проведено более подробно). Литература 1. Абель П. Язык Ассемблера для IBM PC и программирования. М.: Высшая школа, 1992. 2. Гейн А.Г., Сенокосов А.И., Шолохович В.Ф. Информатика. М.: Дрофа, 1998. 3. Сенокосов А.И., Гейн А.Г. Информатика. М.: Просвещение, 1995. 4. Информатика. Базовый курс. 7–9-е классы. / И.Г. Семакин, А.Л. Залогова, С.В. Русаков, Л.В. Шестакова. М.: БИНОМ, 2004. 5. Семакин И.Г. Информатика. Беседы об информации, компьютерах и программах. Ч. 2. Пермь: Изд-во Пермского университета, 1997. |