- •Системный отладчик debug
- •2.1. Общие сведения
- •2.2. Командный язык отладчика
- •Войти в режим ассемблирования командой
- •Перейдем в режим ассемблирования
- •Провести р-трассировку. Для этого сначала выполнить команду:
- •После этого провести обычную детальную т-трассировку
- •Команда
- •Команда
- •Команда
- •По команде
- •Предположим, необходимо заменить диагностические сообщения в воот-секторе на свои собственные. Для этого выполним последовательность действий.
- •2.3. Общий список команд программы debug
2.2. Командный язык отладчика
Ввод команд завершается всегда командой Enter.
А - (Assemble) команда аcсемблирования. Эта команда позволяет вводить программы с использованием мнемокода команд процессора в оперативную память. Ввод команды
А [<адрес>]
заставляет его перейти в режим приема команд с клавиатуры и последовательного размещения их, начиная с адреса, указанного в команде (<адрес>). По умолчанию (если просто А) оттранслированная программа загружается, начиная с адреса CS:0100H в случае, когда команда Assemble используется впервые, или в область за последней командой Assemble.
Все числа в этой команде представляются в шестнадцатеричном виде.
При вводе можно использовать две популярные инструкции ассемблера DB и DW. Например:
DB 1,2,3,"EXAMPLE" (Define Byte – определить байт)
DW 1000,2000,"FFFF" (Define Word – определить слово)
Отладчик поддерживает мнемоники всех команд процессора. При ассемблировании команд JMP и CALL по умолчанию, если это возможно, используется SHORT-вариант этих команд. Но можно указывать перед адресом перехода NEAR и FAR, что приведет к генерации соответствующих команд.
Мнемоникой оператора RET, соответствующего дальнейшему вызову CALL FAR, является RETF. Возможно, а в сомнительных случаях необходимо, использовать указатели WORD PTR или BYTE PTR. При вводе программы допускается печать префиксов CS:, ES:, SS: впереди команды в той же строке.
Пример 1.
Ввести программу в следующей последовательности:
А 100
1D27:0100 SUB СХ,СХ |
; обнуление регистра СХ |
1D27:0102 LOOP 102 |
; 1-й цикл |
1D27:0104 LOOP 104 |
; 2-й цикл |
1D27:0106 INT 20 |
; выход из программы в DEBUG |
Выход из режима ввода программы осуществляется нажатием клавиши <Enter> после перехода к пустой строке вслед за последней командой программы.
Пояснение. В данном примере показан метод организации задержки путем «прокрутки» двух пустых циклов.
Запустить эту программу можно, набрав команду:
G=100
Пример 2.
Здесь приведена программа забивки экрана символом "!"
A 200
1D27:0200 MOV CX,1000 ; установка в счетчик количества
; повторений
1D27:0203 MOV AX,0E21 ; установка в регистр АХ кода
; символа "!" (код 21H) в верхнем
; регистре (код 0ЕH)
1D27:0206 INT 10 ; прерывание по выводу символа
; "!" на экран
1D27:0208 LOOP 203 ; возврат на адрес 0203 (цикл для
; вывода следующего символа "!"
1D27:020A INT 20 ; команда возврата управления
; отладчику (на монитор)
Пояснение. В конце программ в примерах 1 и 2 стоит команда INT 20, обеспечивающая возврат управления обратно на монитор команд отладчика.
Запуск последней программы осуществляется по команде :
G=200
Порядок записи программы из примера 2 и результат ее выполнения приведены на рис. 2.2.
Рис. 2.2. Запись программы из примера 2 в отладчике и результат ее выполнения
С - (Compare) команда сравнения. Эта команда сравнивает побайтно две области памяти и имеет формат:
С <адрес1> L<длина> <адрес2>
и печатает все различия между ними (ошибки сравнения) в форме
<адрес1> <содержимое1> <содержимое2> <адрес2>
В данной записи слева приведена информация о первой области памяти, а справа - о второй. Адреса одного сегмента могут быть представлены смещениями либо полно.
Адреса сравниваемых областей памяти в разных сегментах описываются только полно.
Если <адрес1> содержит только смещение, то соманда С принимает по умолчанию сегмент, содержащийся в регистре DS.
Пример 1.
4 байт памяти, начиная с адреса DS:100, сравнить с 4 байтами, заданными по адресу DS:200.
Для этого ввести команду:
С 100 L4 200
Результат выполнения приведен на рис. 2.3.
Рис. 2.3. Выполнение команды Compare из примера 1.
Пример 2.
Сравнить два блока памяти длиной 256 байт. Первый начинается с адреса 0100, второй с адреса 0300.
Команда:
С 100 LFF 300
Пример 3.
Сравнить первые 10016 байт оперативной памяти с последними.
Команда:
С 0000:0000 L100 F000:FF00
Команда сравнения может быть полезна, например, при проверке на идентичность двух дискетт. Для этого в соседние области памяти загружаются интересующие нас соответствующие блоки этих дискетт, которые затем анализируются командой С.
D - (Dump) дамп оперативной памяти. Эта команда дает на дисплее распечатку указанной области оперативной памяти адресов указанной области оперативной памяти, представляемых в шестнадцатиричной системе исчисления, а справа дает их ASCII-эквиваленты. Причем, кодовые комбинации, не имеющие символьного представления в стандарте ASCII, изображаются точками.
Формат команды:
D [<адрес блока>] [L<длина блока >]
В строке отображается шестнадцать байт. При этом справа указывается полный адрес самого левого байта. Таким образом, в одной строке приводится шестнадцатиричный дамп, а также ASCII- дамп шестнадцати байт оперативной памяти.
Если команда D дана без параметров, то всего на экране отображается 128 байт (80H) в восьми строках, а начальным адресом будет адрес DS:0100.
В каждой строке имеется знак «-», разделяющий 16 байт пополам: между восьмым и девятым байтами.
Пример 1.
Просмотреть дамп последних 255 байт из ПЗУ (BIOS).
Для этого выполнить команду:
D FF00:0000 LFF
Результат выполнения на рис. 2.4.
Пример 2.
Просмотреть указатели-вектора первых тридцати двух прерываний (20H).
Для этого ввести команду:
D 0000:0000 7F
Другой вариант без указания диапазона:
D 0000:0000 - выводятся те же 8 строк (128 байт).
Первые четыре байта дают адреса сегмента и смещения вектора прерывания INT 0, следующие четыре INT 1 и т.д. Внимание! Как указано в п.1.4, порядок записи обратный.
Пример 3.
Просмотреть область оперативной памяти, используемой BIOS.
Для этого набрать:
D 0040:0000 L100
Если периодически несколько раз повторять эту команду, то при сравнении исходной и последующих распечаток имеются изменения в некоторых местах, в частности, происходит увеличение содержимого четверки байтов, начинающейся с адреса 0040:006С. Дело в том, что именно по этому адресу хранится четырехбайтный счетчик системных часов.
Е - (Enter) команда изменения содержимого байтов. Эта команда позволяет побайтно просматривать содержимое памяти вперед и назад, и в случае необходимости, изменять содержимое просматриваемых байтов.
Ввод команды
Е <адрес> [<список>]
вызывает переход отладчика в режим редактирования отдельных байтов. Замена содержимого памяти, начиная с указанного адреса. Список может быть задан в 16-ричных кодах и в кодах ASCII. В последнем случае список заключается в кавычки.
Если параметр <адрес> является относительным адресом в сегменте, то команда будет работать с сегментом, указанным в регистре DS.
Если команда введена без списка, то выводится содержимое ячейки памяти по адресу и приглашение. Можно набрать новое значение, либо оставить прежнее.
Затем набирается один из управляющих символов:
-
"пробел", что означает переход к редактированию следующего байта;
-
«ENTER». Это приведет к выходу из режима побайтного редактирования на командный уровень отладчика;
-
« - ». Нажатие этого знака приведет к переходу на редактирование предыдущего байта.
Пример 1.
Команда
E DS:100 F3 "xyz" 8D
загружает 5 элементов указанного списка в область памяти, ограниченную адресами DS:0100 - DS:0104 (см. рис.2.5). На этом же рисунке результат проверки записи командой D (вторая команда).
Пример 2.
Изменить содержимое четырех последовательных байтов памяти, начиная с адреса 6800:0100, на значения 70, 1F, A4, CE. Посмотреть результат записи.
Для этого ввести команду
E 6800:0100
и набрать четыре заданных в условии числа, разделенных пробелами, затем символ возврата каретки. Далее необходимо выполнить команду D 6800:0100 LF. Результат выполнения действий приведен на рис. 2.5 (3 и 4 команды).
F - (Fill) команда заполнения. Эта команда позволяет заполнить содержимое указанного диапазона оперативной памяти повторяющейся цепочкой байтов c заданными значениями. В частности, когда цепочка состоит из одного байта, эта команда позволяет обнулить нужную область памяти, когда байт равен 0, а также занести во все биты единицу, заполняя байтом равным FF.
Команда имеет следующий формат:
F <диапазон памяти> <цепочка байтов>
Пример 1.
Команда
F 110 L18 00
заполнит область памяти, начинающуюся с адреса DS:0110, нулями общим числом 24 байта (так как имеется указатель L18). Это можно проверить командой:
D 100 L30
(область просмотра L30 задана с запасом)
Пример 2.
Команда
F 5000 L1F 00 FF
заполнит отрезок памяти длиной 31 байт (1FН) повторяющейся парой байтов 00 FF, начиная с адреса DS:5000.
Пример 3.
Заполняющие данные можно задавать в кодах ASCII:
F 4000:0000 L10 "X Y Z"
На рис. 2.6 приведены результаты выполнения команд из примеров 1, 2 и 3. В последнем выведенном дампе код 20H между кодами символов X, Y и Z соответствует пробелу.
Пример 4.
Следующая команда заполняет область памяти, являющуюся текстовым дисплейным буфером:
F В800:0000 L1000 41 05 41 15 41 85
При выполнении результат будет немедленно виден на экране.
G – (Go) команда запуска программы. Эта команда предназначена для запуска загруженной программы на исполнение.
Внимание!
-
Если той области памяти, где хранятся данные, передается управление как программе, компьютер «зависает», и требуется его повторный запуск.
-
В случае, когда в программе имеются серьезные ошибки (например, отсутствует оператор INT 20 возврата на командный уровень отладчика), попытка исполнить ее с помощью оператора G также приводит к зависанию компьютера.
Формат команды:
G[=<адрес>] [<другой адрес1>] [<другой адрес2>] .. (до 10)
Этот оператор обычно используется в одной из следующих четырех форм:
а) G
Исполнение этого оператора сводится к передаче управления адресу CS:IP. Значения CS и IP можно узнать, набрав команду R дампа всех регистров процессора (см. ниже);
б) G=<адрес>
При этом производится запуск программы по указанному адресу. Например, оператор
G=FFFF:0000
приводит к запуску процедуры POST;
в) G <адрес>
В этом случае программа запускается с адреса CS:IP и при достижении оператора с указанным адресом осуществляется BREAK-остановка исполнения программы. При этом на экран выводятся: содержимое регистров, флагов и очередная команда.
Внимание! Распространенной ошибкой начинающих является пропуск знака [ = ] при использовании команды G. В этом случае указанный адрес воспринимается как адрес останова, и если CS:IP указывал, например, на область данных, то компьютер «зависнет».
г) G=<адрес> <другой адрес>
В этом случае производится запуск программы с указанного после знака [ = ] адреса и в случае достижения программой команды с величиной адреса, указанного вторым (другой адрес), происходит остановка.
Такой способ остановки программы называется введением контрольной точки останова. При указании контрольной точки останова соответствующий байт команды по этому адресу заменяется командой INT 3, имеющей размер 1 байт. При достижении контрольной точки исходное значение байта восстанавливается. Команда допускает до 10 точек останова, применение которых удобно для тестирования и отладки программ.
Пример.
Сначала введем программу:
А 100 |
; команда ассемблирования |
MOV ВХ,10 |
|
MOV WO[BX+110],1234 |
|
DEC ВХ |
; здесь ставим контрольную точку |
DEC ВХ |
|
JNE 103 |
|
INT 20 |
|
Запустим программу командой
G=100 109
Программа, дойдя до адреса 109, остановливается и дает полный дамп регистров (рис.2.7).
Н – (Hexarithmetic) команда шестнадцатеричной (гекс) арифметики. Эта команда позволяет получить сумму и разность двух указанных в команде шестнадцатеричных чисел.
Формат команды:
Н <число1> <число2>
Пример 1.
Команда
Н 19F 10А
дает на экране ответ:
02А9 |
0095 |
(сумма) |
(разность) |
Пример 2.
Команда
H 0 1
дает ответ:
1 |
FFFF |
(сумма) |
(разность) |
I – (Input) команда ввода из порта. Эта команда позволяет прочесть содержимое (байт) порта ввода/вывода с указанным адресом, распечатав его на экране в шестнадцатеричном виде.
Формат команды:
I <адрес порта>
Пример 1.
Выполним команду:
I 61
При этом получим содержимое порта В из программируемого периферийного интерфейса 8255.
Исполнив также команду
I 62 ,
получим содержимое порта С этого адаптера.
В программе TECHHELP и других имеется расшифровка значений отдельных битов этих портов, используя которую можно получить полезную информацию о компьютере.
Пример 2.
Команда
I 40
дает состояние младшего байта счетчика системных часов. А исполнение команды I 42 с ее повторением дает младший и старший байты счетчика, связанного с динамиком.
L – (Load) команда загрузки с диска. Эта команда позволяет загружать как логические сектора с флоппи-дисков и винчестеров, так и отдельные файлы. Одна команда может загрузить до 80 секторов (шестнадцатирично).
Загрузка секторов с диска производится командой:
L [<адрес> <номер диска> <начальный сектор> <число секторов>]
Здесь <адрес> означает начальный адрес в оперативной памяти, начиная с которого будет последовательно размещаться содержимое блоков-секторов. Переменная <номер диска> указывает с какого диска будет производиться загрузка. Число 0 означает диск А, число 1 -диск В, число 2 - диск С и т. д. Следующие две переменные соответственно указывают с какого сектора начинается чтение и общее число прочитанных секторов.
Замечание. Если во время чтения с диска появилась ошибка, то программа DEBUG выводит на экран сообщение. После нажатия клавиши F3 на экране снова появится строка команды Load; затем нужно нажать клавишу <Enter>.
Пример1.
Загрузить ВООТ-сектор с флоппи-диска А: в оперативную память, начиная с адреса DS:1000.
Для этого необходимо выполнить команду
L 1000 0 0 1
Затем содержимое ВООТ-сектора можно распечатать командой
D 1000 L200,
а также дизассемблировать:
U 1000 L200
Пример 2.
Загрузка ВООТ-блока винчестера с диска С: в оперативную память, начиная с адреса DS:2000 осуществляется командой
L 2000 2 0 1
Затем этот блок можно просмотреть также, как в примере 1 командами:
D 2000 L200
U 2000 L200
Пример 3.
Загрузка таблицы размещения файлов FAT с диска А: (1,44 М) производится командой:
L 1000 0 1 9
Затем можно просмотреть содержимое FAT-таблицы многократно выполненной командой:
D , начиная с адреса 1000
Задание. Выполнить Пример 3 сначала для пустого отформатированного флоппи-диска, а потом с записанными на нем двумя-тремя файлами.
Пример 4.
Загрузка корневого каталога флоппи-диска на 1,44 М, находящегося на диске А: и его просмотр производятся командами:
L 1000 0 13 F
D 1000
Загрузка файлов в оперативную память также возможна с применением команды Load. Это действие производится в два этапа. Сначала надо командой N указать отладчику имя необходимого файла:
N <имя файла>
Далее необходимо исполнить команду L без аргументов. В результате этих действий файл (за исключением файлов с расширением .ЕХЕ), будет загружен в оперативную память, начиная с адреса CS:100. Если загружаемый файл имеет расширение ЕХЕ, то отладчик расшифрует PSP (префикс сегмента программы) и в соответствии с полученной при этом информацией загрузит файл, начиная с адреса СS:0000. Число прочитанных байтов хранится в регистровой паре ВХ:СХ после выполнения команды L.
Пример 5. Загрузка файла COMMAND.COM в оперативную память для его возможного изучения:
N C:\COMMAND.COM
L
М – (Move) команда копирования содержимого части оперативной памяти в другую область оперативной памяти.
Формат команды:
М <диапазон> <начальный_адрес>
Здесь <диапазон> указывает на копируемую область памяти, а <начальный адрес> - на адрес первого байта, начиная с которого размещаются скопированные данные. Эту команду можно использовать для временного сохранения содержимого оперативной памяти с ее последующим восстановлением.
Замечания:
-
Если в параметре <диапазон> в качестве начального адреса выступает относительный адрес в сегменте, то команда М относится к сегменту, указанному регистром DS. Конечный адрес также должен представлять собой относительный адрес в этом сегменте.
-
Если параметр <начальный адрес> является относительным адресом начала, то команда М относится к сегменту, указанному регистром DS.
Пример 1.
Выполним последовательность действий с применением команды Move:
-
просмотрим содержимое 16 байт памяти (10H), начиная с адреса DS:0100:
D 100 L10
-
сохраним данные этих ячеек в памяти, начиная с адреса DS:1000
М 100L10 1000
-
затрем исходное содержимое (запишем значение "0")
F 100L10 0
-
проверим обнуление
D 100L10
-
восстановим исходное содержимое
М 1000L10 100
-
проверим результат восстановления
D 100 L10
Последовательность этих действий и результаты их выполнения показаны на рис. 2.8.
Пример 2.
Команда
М CS:100 110 500
переписывает 17 байтов из области CS:100 – CS:110 в область, начинающуюся с адреса DS:500.
Пример 3.
Переписать 20 байтов из ПЗУ в ОЗУ.
Воспользуемся командой
M F000:C027 L20 00A0:0000
С копией в ОЗУ можно выполнять все: изменять, запускать на исполнение.
Эту команду можно также использовать для редактирования программ, отлаживаемых или разрабатываемых в среде отладчика. Особенно она полезна при вставке новых операторов в тело программы.
Пример 4.