Автор: Пользователь скрыл имя, 10 Марта 2013 в 15:44, курс лекций
Один из основных принципов машины фон Неймана — то, что и программы, и данные хранятся в одной и той же памяти. Сохраняемая в памяти программа представляет собой некоторые коды, которые могут рассматриваться как данные. Возможно, с точки зрения программиста программа — активный компонент, она выполняет некоторые действия. Но с точки зрения процессора команды программы — это данные, которые процессор читает и интерпретирует. С другой стороны программа — это данные с точки зрения обслуживающих программ, например, с точки зрения компилятора, который на входе получает одни данные — программу на языке высокого уровня (ЯВУ), а на выходе выдает другие данные — программу в машинных кодах.
Загрузите в память DEBUG и введите для INT 12H и RET следующие машинные коды:
E CS:100 CD 12 CB
Нажмите R (Enter) для отображения содержимого регистров и первой команды. Регистр IP содержит 0100, при этом высвечивается команда INT 12H.
Теперь нажмите T (и Enter) несколько раз и просмотрите выполняемые команды BIOS (отладчик показывает мнемокоды, хотя в действительности выполняются машинные коды). В этот момент регистр AX содержит размер памяти в шестнадцатеричном формате. Теперь введите еще раз команду T для выхода из BIOS и возврата в вашу программу. На экране появится команда RET для машинного кода CB, который был введен вами.
4
Специальные средства отладчика
В операционной системе DOS можно использовать DEBUG для ввода команд Ассемблера так же, как и команд машинного языка. На практике можно пользоваться обоими методами.
Команда A
Команда отладчика A (Assemble) переводит DEBUG в режим приема команд Ассемблера и перевода их в машинные коды.
Команда U
Команда отладчика U (Unassemble) показывает машинные коды для команд Ассемблера. Необходимо сообщить отладчику адреса первой и последней команды, которые необходимо просмотреть
Ввод программы обычно используется на языке Ассемблера, когда машинный код неизвестен, а ввод в машинном коде — для изменения программы во время выполнения. Однако в действительности программа DEBUG предназначена для отладки программ.
Сохранение программы из отладчика
Можно использовать DEBUG для сохранения программ на диске в следующих случаях:
1. После загрузки программы в память машины и ее модификации необходимо сохранить измененный вариант. Для этого следует:
u загрузить программу по ее имени: DEBUG n:имя файла [Enter]
u просмотреть программу с помощью команды D и ввести изменения по команде E
u записать измененную программу: W [Enter]
2. Необходимо с помощью DEBUG написать небольшую по объему программу и сохранить ее на диске. Для этого следует:
u вызвать отладчик DEBUG
u с помощью команд A (assemble) и E (enter) написать программу
u присвоить программе имя: N имя файла.COM [Enter].
Тип программы должен быть COM — так как только программист знает, где действительно кончается его программа, указать отладчику длину программы в байтах.
u запросить регистр CX командой: R CX [Enter] — отладчик выдаст на этот запрос CX 0000 (нулевое значение)
u указать длину программы — 6
u записать измененную программу: W [Enter]
В обоих случаях DEBUG выдает сообщение «Writing nnnn bytes» (Запись nnnn байтов). В случае, если nnnn равно 0, то произошла ошибка при вводе длины программы, и необходимо повторить запись cнова.
Важно: Отладчик DOS DEBUG это средство, полезное для отладки ассемблерных программ. Однако следует быть осторожным с ее использованием, особенно для команды E (ввод). Ввод данных в неправильные адреса памяти или ввод некорректных данных могут привести к непредсказуемым результатам.
На экране в этом случае могут появиться «странные» символы, клавиатура заблокирована или даже DOS прервет DEBUG и перезагрузит себя с диска. Какие-либо серьезные повреждения вряд ли произойдут, но возможны некоторые неожиданности, а также потеря данных, которые вводились при работе с отладчиком.
В случае, если данные, введенные в сегмент данных или сегмент кодов, оказались некорректными, следует, вновь используя команду E, исправить их. Однако, можно не заметить ошибки и начать трассиpовку программы. Но и здесь возможно еще использовать команду E для изменений. В случае, если необходимо начать выполнение с первой команды, то следует установить в регистре командного указателя (IP) значение 0100.
Введите команду R (register) и требуемый регистр в следующем виде:
R IP [Enter]
Отладчик выдаст на экран содержимое регистра IP и перейдет в ожидание ввода. Здесь следует ввести значение 0100 и нажать для проверки результата команду R (без IP). Отладчик выдаст содержимое регистров, флагов и первую выполняемую команду. Теперь можно, используя команду T, вновь выполнить трассировку программы.
В случае, если ваша программа выполняет какие-либо подсчеты, то возможно потребуется очистка некоторых областей памяти и регистров. Но yбедитесь в сохранении содержимого регистров CS, DS, SP и SS, которые имеют специфическое назначение.
Лекция 14.
Макросредства
4
Простое макроопределение
Для каждой закодированной
команды Ассемблер генерирует одну
команду на машинном языке. Но для
каждого закодированного
Ассемблер MASM также имеет макросредства, но макросы здесь определяются программистом. Для этого задается имя макроса, директива MACRO, различные ассемблерные команды, которые должен генерировать данный макрос и для завершения макроопределения — директива MEND. Затем в любом месте программы, где необходимо выполнение определенных в макрокоманде команд, достаточно закодировать имя макроса. В результате Ассемблер сгенерирует необходимые команды.
Использование макрокоманд позволяет:
u упростить и сократить исходный текст программы;
u сделать программу более понятной;
u уменьшить число возможных ошибок кодирования.
Примерами макрокоманд могут быть операции ввода-вывода, связанные с инициализацией регистров и выполнения прерываний преобразования ASCII и двоичного форматов данных, арифметические операции над длинными полями, обработка строковых данных, деление с помощью вычитания.
Макроопределение должно находиться до определения сегмента.
Директива MACRO указывает Ассемблеру, что следующие команды до директивы ENDM являются частью макроопределения.
Директива ENDM завершает макроопределение. Команды между директивами MACRO и ENDM составляют тело макроопределения.
Имена, на которые имеются ссылки в макроопределении должны быть определены где-нибудь в другом месте программы.
Макрокоманда INIT1 может использоваться в кодовом сегменте там, где необходимо инициализировать регистры. Когда Ассемблер анализирует команду INIT1, он сначала просматривает таблицу мнемокодов и, не обнаружив там соответствующего элемента, проверяет макрокоманды. Так как программа содержит определение макрокоманды INIT1 Ассемблер подставляет тело макроопределения, генерируя необходимые команды — макрорасширение.
Программа использует рассматриваемую макрокоманду только один раз, хотя имеются другие макрокоманды, предназначенные на любое число применений и для таких макрокоманд Ассемблер генерирует одинаковые макрорасширения.
4
Использование параметров в макрокомандах
Формальные параметры в макроопределении указывают Ассемблеру на соответствие их имен любым аналогичным именам в теле макроопределения. Формальные параметры могут иметь любые правильные ассемблерные имена, не обязательно совпадающими именами в сегменте данных.
Формальный параметр может иметь любое правильное ассемблерное имя (включая имя регистра, например, CX), которое в процессе ассемблирования будет заменено на параметр макрокоманды. Отсюда следует, что Ассемблер не распознает регистровые имена и имена, определенные в области данных, как таковые. В одной макрокоманде может быть определено любое число формальных параметров, разделенных запятыми, вплоть до 120 колонки в строке.
4
Комментарии
Для пояснений назначения макроопределения в нем могут находиться комментарии. Директива COMMENT или символ точка с запятой указывают на строку комментария, как это показано в следующем макроопределении PROMPT:
PROMPT MACRO MESSGE ;Эта макрокоманда выводит сообщения на экран
MOV AH,09H
LEA DX,MESSGE
INT 21H
ENDM
Так как по умолчанию в листинг попадают только команды генерирующие объектный код, то Ассемблер не будет автоматически выдавать и комментарии, имеющиеся в макроопределении.
В случае, если необходимо, чтобы в расширении появлялись комментарии, следует использовать перед макрокомандой директиву .LALL («list all» — выводить все), которая кодируется вместе с лидирующей точкой:
.LALL PROMPT MESSAG1
Макроопределение
может содержать несколько
По умолчанию в Ассемблере действует директива .XALL, которая выводит в листинг только команды, генерирующие объектный код. И, наконец, можно запретить появление в листинге ассемблерного кода в макрорасширениях, особенно при использовании макрокоманды в одной программе несколько раз.
Для этого служит директива .SALL («suppress all» — подавить весь вывод), которая уменьшает размер выводимого листинга, но не оказывает никакого влияния на размер объектного модуля.
Директивы управления листингом .LALL, .XALL, .SALL сохраняют свое действие по всему тексту программы, пока другая директива листинга не изменит его. Эти директивы можно размещать в программе так, чтобы в одних макрокомандах распечатывались комментарии, в других — макрорасширения, а в третьих подавлялся вывод в листинг.
4
Использование макрокоманд в
Макроопределение может содержать ссылку на другое макроопределение.
Рассмотрим простое макроопределение DOS21, которое заносит в регистр AH номер функции DOS и выполняет INT 21H:
DOS21 MACRO DOSFUNC
MOV AH,DOSFUNC
INT 21H
ENDM
Для использования данной макрокоманды при вводе с клавиатуры необходимо закодировать:
LEA DX,NAMEPAR DOS21 0AH
Предположим, что имеется другое макроопределение, использующее функцию 02 в регистре AH для вывода символа:
DISP MACRO CHAR
MOV AH,02
MOV DL,CHAR
INT 21H
ENDM
Для вывода на экран, например, звездочки достаточно закодировать макрокоманду DISP '*'. Можно изменить макроопределение DISP, воспользовавшись макрокомандой DOC21:
DISP MACRO CHAR
MOV DL,CHAR
DOS21 02
ENDM
Теперь, если закодировать макрокоманду DISP в виде DISP '*', то Ассемблер сгенерирует следующие команды:
MOV DL,'*'
MOV AH,02
INT 21H
4
Директива LOCAL
В некоторых
макрокомандах требуется
При использовании
такой макрокоманды в программе
более одного раза происходит также
неоднократное определение
Для обеспечения уникальности генерируемых в каждом макрорасширении имен используется директива LOCAL, которая кодируется непосредственно после директивы MACRO, даже перед комментариями. Общий формат имеет следующий вид:
LOCAL dummy-1,dummy-2,... ;Формальные параметры
4
Использование библиотек макроопределений
Определение таких макрокоманд, как INIT1 и INIT2 и одноразовое их использование в программе кажется бессмысленным. Лучшим подходом здесь является каталогизация собственных макрокоманд в библиотеке на магнитном диске, используя любое описательное имя, например, MACRO.LIB:
INIT MACRO CSNAME,DSNAME,SSNAME .
.
ENDM PROMPT MACRO MESSGE .
.
ENDM
Теперь для использования любой из каталогизированных макрокоманд вместо MACRO определения в начале программы следует применять директиву INCLUDE:
INCLUDE C:MACRO.LIB .
.
INIT CSEG,DATA,STACK
В этом случае Ассемблер обращается к файлу MACRO.LIB (в нашем примере) на дисководе C и включает в программу оба макроопределения INIT и PROMPT.
Хотя в нашем примере требуется только INIT. Ассемблерный листинг будет содержать копию макроопределения, отмеченного символом C в 30 колонке LST-файла.
Следом за макрокомандой идет ее расширение с объектным кодом и с символом плюс (+) в 31 колонке.
Так как транслятор с Ассемблера является двухпроходовым, то для обеспечения обработки директивы INCLUDE только в первом проходе (а не в обоих) можно использовать следующую конструкцию:
IF1 INCLUDE C:MACRO.LIB ENDIF
IF1 и ENDIF являются
условными директивами.
Директива ENDIF завершает IF-логику. Таким образом, копия макроопределений не появится в листинге — будет сэкономлено и время и память.
Директива очистки
Директива INCLUDE указывает Ассемблеру на включение всех макроопределений из специфицированной библиотеки.
Например, библиотека
содержит макросы INIT, PROMPT и DIVIDE, хотя программе
требуется только INIT. Директива PURGE
позволяет «удалить»
IF1 INCLUDE MACRO.LIB ;Включить всю библиотеку
ENDIF PURGE PROMRT,DIYIDE ;Удалить ненужные макросы ...
INIT CSEG,DATA,STACK ;Использование оставшейся макрокоманды
Директива PURGE действует только в процессе ассемблирования и не оказывает никакого влияния на макрокоманды, находящиеся в библиотеке.