Материал: Системное программирование

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

7.2. Отладка программы

Отладчик DEBUG позволяет управлять процессом исполнения программы. С его помощью можно выводить на экран содержимое всех регистров, содержимое памяти, он имеет функции пошагового выполнения и возможность использования контрольных точек. Рассмотрим действия, которые необходимо выполнить для пошагового исполнения программы под отладчиком DEBUG. Выполним следующую команду (расширение EXE указывать обязательно):

DEBUG FIRST.EXE

Произойдет запуск отладчика и появится приглашение в виде знака дефиса (-). Некоторые наиболее используемые команды отладчика описаны в табл. 74. В квадратных скобках заключены необязательные параметры команд. Например, для выполнения всей программы от начала до конца под отладчиком нужно набрать команду G, а для выполнения до инструкции MOV AH, 9 – команду G 0011. Здесь адрес 0011h соответствует инструкции MOV AH, 9 и называется контрольной точкой. Для просмотра всех регистров служит команда R, а для записи значения, например, в регистр AX – команда R AX.

Табл. 74. Общеупотребительные команды отладчика DEBUG.

Команда

Действие

D адрес

D адрес_начала адрес_конца

Вывести содержимое ячеек памяти.

E адрес значение 1 [значение 2…]

Изменить содержимое ячеек памяти.

F адрес_начала L значение байта

Заполнить область памяти заданным значением.

G [смещение 1] [смещение 2…]

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

Q

Выйти из отладчика в MS-DOS.

R [имя_регистра]

Вывести содержимое одного или всех регистров.

Если указан только один регистр, можно изменить

его содержимое.

T [число_команд]

Исполнить заданное число команд и вывести содержимое регистров на каждом шаге.

Если параметр не задан, будет происходить

пошаговое выполнение команд.

U [адрес]

Транслировать содержимое ячейки памяти в команду.

Команда T инициирует выполнение одной или нескольких машинных инструкций. После ее выполнения отображается содержимое всех регистров, включая состояния флагов регистра флагов. Значения двухбуквенных мнемокодов регистра флагов приведены в табл. 75.

Табл. 75. Мнемокоды регистра флагов.

Название флага

Установлен

Сброшен

Переполнение

OV

NV

Направление

DN

UP

Прерывание

EI

DI

Знак

NG

PL

Нуль

ZR

NZ

Вспомогательный перенос

AC

NA

Четность

PE

PO

Перенос

CY

NC

На рис. 27 изображен типичный сеанс работы программы под отладчиком. Показана последовательность действий по проверке алгоритма работы команды смещения SHL. В данный момент регистр CL загружен числом 0Ah и выполнена команда SHL. В результате в регистр AX помещено значение 0400h.

Следующая команда пересылки передает это число в сегмент данных по смещению 0001. Команда отладчика d ds:0 позволяет просмотреть сегмент данных, начиная с нулевого адреса. Видно, что по нулевому адресу в сегменте данных находится число 01, а в следующих двух байтах 00 и 04 (т.е. в обратном порядке число 400h = 1024). Как видно, этот участок программы работает правильно. Для выхода из отладчика необходимо набрать команду q.

Рис. 27. Сеанс исполнения программы FIRST.EXE с помощью отладчика DEBUG.

Таков процесс разработки программы на языке ассемблера. Последовательность выполненных нами действий показана на рис. 28. Все они справедливы для разработки и отладки программ любого уровня сложности.

В общем случае объем программы может быть таким, что она не сможет поместиться в отведенный ей сегмент кода. Вспомним, размер программного сегмента не должен превышать 64 КБ. Если размер сегмента кода и данных не превышают это значение, то программа является одномодульной. В противном случае мы имеем многомодульную программу.

Рис. 28. Трансляция, компоновка и отладка программы FIRST.

Контрольные вопросы

  1. Опишите этапы разработки одномодульной программы в среде TASM.

  2. Для чего необходим файл листинга и какова его структура.

  3. Перечислите основные команды отладчика.

8. Разработка многомодульных программ

Разработка многомодульных программ ведется в соответствии с принципом физической декомпозиции, когда формируется набор взаимосвязанных модулей, каждый из которых выполняет определенную задачу общего процесса. Каждый модуль независимо от остальных транслируется в объектный модуль. Затем все объектные модули объединяются в единую машинную программу с помощью компоновщика TLINK (рис. 29)

Рис. 29. Трансляция и компоновка многомодульной программы.

Например, если программа состоит из двух объектных модулей M1.OBJиM2.OBJ, то команда компоновки будет следующей:

TLINK M1+M2,M

В первом параметре через символ «+» перечисляются имена всех объектных модулей (если расширение OBJ, его можно не указывать), а второй параметр указывает имя исполняемого файла.

8.1. Принципы разработки модулей

Каждый модуль многомодульной программы представляет последовательность предложений, с последней директивой END:

< предложение >

...

< предложение >

END [< точка входа >]

Среди модулей должен быть выделен основной (главный), с которого начинается выполнение программы и который передает управление остальным модулям. Главный модуль отличается наличием точки входа. Если точка входа определена и в других модулей, главным модулем будет считаться тот, что был указан первым в параметрах компоновщика.

Все имена, объявленные в модуле, локализуются в нем. Это позволяет исключить конфликты между модулями при использовании одинаковых имен для идентификаторов, меток и подпрограмм.

Для возможности использования идентификаторов, меток и подпрограмм в других модулях они должны быть экспортированы. Для этого существует специальная директива:

PUBLIC < имя >,..., < имя >

Директива может быть указана в любом месте модуля любое число раз. Однако обычно для удобства ее помещают в самом начале модуля.

С другой стороны, модуль, импортирующий идентификаторы, метки и подпрограммы, должен продекларировать их с помощью директивы:

EXTRN < имя > : < тип >,..., < имя > : < тип >

где < тип > – тип данных BYTE, WORD, DWORD, ABS, NEAR или FAR.

Директива также может быть указана в любом месте модуля любое число раз. Типы BYTE, WORD и DWORD используются для имен переменных, тип ABS – для имен констант, NEAR и FAR – для меток или имен процедур.

Рассмотрим применение директив PUBLIC и EXTRN. Следующий модуль экспортирует процедуру PRC и переменную IDW:

PUBLIC PRC, ID

DATASG SEGMENT

IDW DW 200h

DATASG ENDS

CODESG SEGMENT

ASSUME CS: CODESG, DS: DATASG

PRC PROC FAR

...

PRC ENDP

CODESG ENDS

END

Второй модуль является главным. Он импортирует объявления первого модуля. Для доступа к переменной IDW необходимо настроиться на программный сегмент DATASG. Однако напрямую обратиться к DATASG невозможно, т.к. имена сегментов запрещено описывать в разделе PUBLIC. Поэтому здесь используется следующий прием.

Вспомним, что оператор SEG позволяет получить адрес сегмента, в котором определен указанный в качестве параметра идентификатор. В нашем примере таким идентификатором будет IDW. С помощью вспомогательного регистра сохраним адрес сегмента данных в дополнительном сегментном регистре ES. Теперь для обращения к переменной IDW необходимо использовать сегментирование по ES:

EXTRN PRC: FAR, IDW: WORD

CODE SEGMENT

ASSUME CS: CODE

S: MOV AX, SEG IDW

MOV ES, AX

...

MOV BX, ES:IDW

...

CODE ENDS

END S

Источник: https://files.student-it.ru/previewfile/284711