2. Отладчик Debug
2.1. Пример работы с отладчиком.
Мы уже посмотрели примеры работы с отладчиком в предыдущей главе. Теперь на очень простом примере продемонстрируем типичный сеанс работы с отладчиком.
Предположим, мы хотим изучить работу команды сложения двух целых чисел. Первое слагаемое хранится в слове со смещением 200h (в текущем сег-менте данных) — оно будет загружено в регистр AX, второе слагаемое — число 2 — будет загружено в регистр BX, сумму требуется разместить в AX. Напишем с этой целью простую программу, содержащую всего три команды.
mov ax,[200h] ; Поместить в аккумулятор содержимое
; слова по адресу DS:200
mov bx,2 ; Поместить в регистр BX число 2 ( BX = 2)
add ax,bx ; Сложить содержимое AX и BX
; и поместить результат в AX ( AX += BX)
Комментарии отделены от текста программы точкой с запятой. (Рекомен-дуется каждую фразу комментария начинать с прописной буквы. Если коммен-тарий продолжается на следующей строке, то продолжение фразы начинается со строчной буквы.) В скобках последние две команды записаны с использова-нием нотации языка Си — так проще запомнить, что первый операнд является приемником, а второй — источником. Следует понимать, что на самом деле эти три команды являются только фрагментом программы на языке ассемблера. Если мы собираемся использовать транслятор (например MASM или TASM), то к этим командам нужно добавить еще ряд директив. Однако для отладчика этих команд достаточно. Еще заметим, что вместо последних двух команд можно было написать одну: add ax,2.
Вызовем отладчик. Для этого наберем в командной строке имя утилиты debug
D:USER>debug
нажмем Enter и получим приглашение к диалогу — дефис.
1) Ассемблирование текста программы. В отладчике имеется мини-ассемблер. Он переводит мнемонику команд в их машинные коды. Практически все команды отладчика вызываются набором одной буквы, далее, возможно, указываются параметры команды. Ассемблирование начинается по команде A (Assemble). Команды можно набирать и большими и малыми буквами. Команда A имеет параметр: адрес в памяти, начиная с которого будут размещены машинные коды. (Здесь необходимо уточнение: полный адрес представлен в виде segment:offset — сегмент:смещение. Как правило, мы будем указывать только смещение). Разместим коды команд, начиная со смещения 100h (этот выбор не случаен: ниже смещения 100h что-либо записывать не рекомендуется, пока вы не изучите структуру области от начала сегмента до смещения 100h — она носит название префикс программного сегмента (Program Segment Prefix — PSP)).
-a100
22B6:0100 mov ax,[200] (суффикс h не указываем!)
22B6:0103 mov bx,2
22B6:0106 add ax,bx
22B6:0108 nop
22B6:0109
В ответ на ввод команды a100 отладчик выдает адрес в формате сег-мент:смещение (на вашей машине сегментная часть адреса может быть другой — в дальнейшем это не оговаривается) и ожидает ввод команды. Набираем ко-манду и нажимаем клавишу Enter. Мнемоника команды немедленно переводит-ся мини-ассемблером в машинный код (чуть ниже мы увидим, как его посмот-реть) и отладчик выводит следующий свободный адрес — 103. Следовательно, код команды mov ax,[200] занимает три байта (с адресами 100, 101, 102). Мы вводим следующую команду и т.д. Завершаем программу командой nop (нет операции). Удобство ее включения в текст программы станет ясным из дальнейшего. В ответ на адрес 109 нажимаем Enter и получаем приглашение отладчика. Обратите внимание, что все числа в debug интерпретируются как 16-ричные, поэтому суффикс h не указывается.
Если какая-либо команда будет введена неправильно, отладчик сообщит об этом и выдаст тот же адрес (естественно — он же не смог транслировать ко-манду):
-a100
22B6:0100 mov ax[200] (пропущена запятая)
^ Error
22B6:0100
Код нашей программы занимает байты с 100-го по 108-й, т.е. девять байтов.
2) Дисассемблирование кода (восстановление мнемоники команд по ма¬шин-но¬му коду).
-u100L9
22B6:0100 A10002 MOV AX,[0200]
22B6:0103 BB0200 MOV BX,0002
22B6:0106 01D8 ADD AX,BX
22B6:0108 90 NOP
Команда расшифровывается так: дисассемблировать (U — Unassemble), на-чиная с 100-го смещения код длиной (L — Length) 9 байтов. (Можно было на-брать команду в иной форме: U100 108, т.е. указать начальный и конечный адреса кода).
Полученные в результате строки имеют формат:
сегмент:смещение машинный код мнемоника
В кодах команд можно увидеть коды операндов в "перевернутом виде": Расшифруем код A10002. A1 — код пересылки содержимого ячейки памяти в аккумулятор, 00 — младший байт и 02 — старший байт операнда-источника. Аналогично расшифровывается код второй команды. Можно убедиться в том, что машинные коды имеют разную длину: в нашем примере — 1, 2 и 3 байта.
3) Заполнение памяти. Перед выполнением программы нужно занести в слово памяти, расположенное по адресу DS:200, число 1. Можно было добавить это действие в нашу программу в качестве первой команды (чуть позже мы узнаем, как это сделать), но мы воспользуемся средствами отладчика. Команда E (Enter — ввод) позволяет занести в память новое содержимое (здесь то, что выводит debug, подчеркнуто):
-e200
22B6:0200 4D.01 E2.00
(нажимаем пробельную клавишу)
Итак, мы вводим команду E и адрес. Отладчик сообщает, что в байте по ад-ресу 200 записано число 4Dh, точка — приглашение к вводу. Набираем 01 (можно и без ведущего нуля) и нажимаем пробельную клавишу, чтобы полу-чить содержимое следующего байта (если бы старое значение байта нас устраи-вало, мы сразу нажали бы пробел). По адресу 201 записано число 0E2h — зано-сим нуль. Завершаем команду E, нажимая Enter.
Команду E можно было ввести и в другой форме, указывая в одной строке адрес и список вводимых байтов (т.е. на этот раз мы не видим прежнее содер-жимое ячеек памяти):
-e200 1 0
Проверим результат занесения уже знакомой командой
-d200L2
22B6:0200 01 00
Записано слово 0001 (младший байт 01, старший байт 00).
Для ввода слова проще воспользоваться уже знакомой командой A:
-a200
22B6:0200 dw 1 (Define Word — задать слово)
Здесь есть одна тонкость. Команда E offset заносит данные по адресу DS:offset, а команда A offset — по адресу CS:offset. Но сейчас содержимое сег-ментных регистров CS и DS совпадает.
4) Содержимое регистров. Перед тем как выполнять программу посмотрим содержимое регистров центрального процессора. Введем команду R (Register):
-r
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=22B6 ES=22B6 SS=22B6 CS=22B6 IP=0100 NV UP EI PL NZ NA PO NC 22B6:0100 A10002 MOV AX,[0200] DS:0200=0001
Отладчик вывел три строки. В первой строке перечислены регистры обще-го назначения и показано их содержимое. Начальное содержимое регистров — нулевое. Только указатель стека SP содержит FFEEh, т.е. показывает на адрес, близкий к концу сегмента. Во второй строке присутствуют сегментные регист-ры DS, ES, SS, CS — в них хранится одинаковый сегментный адрес; счетчик команд IP содержит смещение 100h; далее перечислены текущие значения флажков в регистре флагов. Отдельные биты этого регистра устанавливаются (1) или сбрасываются (0) по результату выполнения команд. Но отладчик пока-зывает не содержимое регистра флагов в шестнадцатеричном представлении, а значения битов в закодированной форме в виде двухбуквенных сокращений. Сведем их в таблицу 3.1.
Таблица 3.1. Кодирование значений флагов в debug.
Флаг Наименование Установлен (‘1’) Сброшен (‘0’)
OF переполнение OV (OVerflow) NV (Non oVerflow)
Есть знаковое переполнение Нет знакового переполнения
DF направление DN (DowN) UP
автоуменьшение указателя при выполнении строковых команд автоувеличение указателя при выполнении строковых команд
IF прерывание EI (Enable Interrupt) DI (Disable Interrupt)
внешние прерывания разрешены внешние прерывания запрещены
SF знак NG (NeGativ) PL (PLus)
результат отрицательный результат неотрицательный
ZF ноль ZR (ZeRo) NZ (Non Zero)
результат нулевой результат ненулевой
AF вспомогательный AC (Adjust Carry) NA (Non Adjust carry)
перенос произошел перенос из младшей тетрады переноса из младшей тетрады не было
PF четность PE (Parity Even) PO (Parity Odd)
сумма битов младшего байта чет-ная сумма битов — нечетная
CF перенос CY (Carry Yes) NC (Non Carry)
установлен флаг переноса флаг переноса сброшен
В третьей строке представлены адрес, код и мнемоника команды, которая будет выполняться первой при запуске на выполнение. Ее сегментный адрес хранится в CS, а смещение в IP (именно этой информацией воспользовался от-ладчик, чтобы отобразить команду). Кроме того, в третьей строке показано со-держимое ячейки памяти, на которую ссылается один из операндов команды.
5) Выполнение программы "по шагам". В этом режиме после каждой ко-манды выполнение будет приостанавливаться. Для этого вводим команду T (Trace — трассировка). Выполняется команда, адрес которой содержится в IP, и показывается информация, как при подаче команды R.
-t
AX=0001 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=22B6 ES=22B6 SS=22B6 CS=22B6 IP=0103 NV UP EI PL NZ NA PO NC
22B6:0103 BB0200 MOV BX,0002
Обратите внимание, что изменилось содержимое только двух регистров: AX — в него загружено значение 1, и IP — в нем адрес следующей выполняе-мой команды. Сама команда показана в третьей строке. Флаги не изменились.
-t
AX=0001 BX=0002 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=22B6 ES=22B6 SS=22B6 CS=22B6 IP=0106 NV UP EI PL NZ NA PO NC 22B6:0106 01D8 ADD AX,BX
-t
AX=0003 BX=0002 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=22B6 ES=22B6 SS=22B6 CS=22B6 IP=0108 NV UP EI PL NZ NA PE NC 22B6:0108 90 NOP
Только теперь (после команды add ax,bx) изменилось содержимое реги-стра флагов. Правда это коснулось только одного флага PF (в младшем байте результата (03h=00000011b) установлено два бита, то есть четное число битов).
6) Внесение изменений в программу: в регистр BX запишем –1. Заменим вторую команду нашей программы.
-a103
22B6:0103 mov bx,-1
22B6:0106
Проверим результат изменений (на всякий случай, хотя и так видно, что длина команды не изменилась):
-u100L9
22B6:0100 A10002 MOV AX,[0200]
22B6:0103 BBFFFF MOV BX,FFFF (дополнительный код числа ¬–1)
22B6:0106 01D8 ADD AX,BX
22B6:0108 90 NOP
Вновь выполним трассировку. Но сейчас в IP содержится 108h, поэтому первая команда трассировки выглядит иначе, чем раньше: после знака равенст-ва указываем стартовый адрес.
-t=100
AX=0001 BX=0002 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=22B6 ES=22B6 SS=22B6 CS=22B6 IP=0103 NV UP EI PL NZ NA PE NC 22B6:0103 BBFEFF MOV BX,FFFE
-t
.............
7) Изменение содержимого регистров. Если наша цель — изучение коман-ды add, то проще изменять значения регистров средствами отладчика непо-средственно перед выполнением команды add. Вновь воспользуемся командой R, но теперь укажем имя регистра:
-rax
AX 0000
:-2
^ Error
Отладчик показывает содержимое AX и запрашивает новое содержимое. Вводим число –2. Отладчик воспримет это как ошибку. Нужно сначала полу-чить дополнительный код –2. Его можно узнать с помощью отладчика. Команда H <1-е число> <2-е число> вычисляет сумму и разность аргументов слов:
-h0 2
0002 FFFE (т.е. 0 + 2 = 0002 и 0 – 2 = 0FFFEh)
Теперь введем в AX дополнительный код числа –2.
-rax
AX 0000
:fffe
Изменим BX
-rbx
BX FFFE
:3
А теперь выполним трассировку только команды сложения.
-t=106
AX=0001 BX=0003 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=22B6 ES=22B6 SS=22B6 CS=22B6 IP=0108 NV UP EI PL NZ AC PO CY 22B6:0108 90 NOP
8) Выполнение всей программы:
-g=100 108
AX=0000 BX=FFFF CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=22B6 ES=22B6 SS=22B6 CS=22B6 IP=0108 NV UP EI PL ZR AC PE CY 22B6:0108 90 NOP
Итак, использована команда G (Go — прогон), далее после знака равенства указываем стартовый адрес, затем адрес точки останова (теперь мы видим пользу команды nop — именно ее адрес служит адресом точки останова). За-метим, что команда g=100 приведет скорее всего к зависанию программы (лучше не проверять это!). Действительно, после наших четырех команд в опе-ративной памяти хранится "мусор", который будет интерпретироваться процес-сором как коды команд.
9) Сохранение файла с программой на диске. Для этого выполним последо-вательность действий:
а) дадим файлу имя pr1.com. Введем команду N (Name — имя)
-npr1.com
(отладчик создает исполняемые файлы только типа .com — не .exe!)
б) в регистры BX и CX занесем длину программы в байтах. BX:CX — длинное беззнаковое целое: в BX — старшие разряды, в CX — младшие разря-ды. Типичная ошибка: забывают занести в BX нуль. В результате на диске об-разуется очень большой файл.
-rbx
BX FFFF
:0
-rcx
CX 0000
:9
Еще раз напомним, что диапазон адресов 100 – 108 имеет длину 9 байтов.
в) введем команду записи на диск W (Write — писать).
-w
Writing 00009 bytes
Отладчик сообщил количество записанных байтов.
10) Выход из отладчика. Вводим команду Q (Quit — мы с отладчиком "кви-ты")
-q
D:USER>_
Убедитесь, что в текущем каталоге действительно имеется файл pr1.com размера 9 байтов. Запускать его на выполнение из командной строки бессмыс-ленно по двум причинам:
• программа не отображает результаты работы на экране, проследить ее работу можно только средствами отладчика;
• в программе нет команд, обеспечивающих возврат в DOS, поэтому после наших четырех команд начнет выполняться "мусор" с непредсказуемыми последствиями.
11) Отладка программы, хранящейся в файле. Мы хотим еще поработать с нашей программой, записанной в файле pr1.com. Начать работу можно двумя способами.
а) Указать имя файла в командной строке при запуске debug:
D:USER> debug pr1.com
-r
AX=0000 BX=0000 CX=0009 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=22B6 ES=22B6 SS=22B6 CS=22B6 IP=0100 NV UP EI PL NZ NA PO NC 22B6:0100 B80100 MOV AX,0001
В BX:CX записан размер считанной программы.
б) Загрузить нужный файл в оперативную память с помощью команд debug:
D:USER> debug
-n pr1.com (назовем имя)
-L (Load — загрузка содержимого файла в оперативную память)
Программа считана с диска. С ней можно работать. После внесения изме-нений в программу может возникнуть желание сохранить новый вариант про-граммы на диске. Для записи на диск достаточно установить нужные BX:CX и ввести команду W, т.к. имя файла уже задано.
Теперь, после того как мы получили представление о возможностях отлад-чика и типовых "связках" команд, дадим систематическое изложение. Отладчи-ки, которые мы будем изучать позже, не будут сопровождаться столь подроб-ным изложением, т.к. для них можно получить информацию в Справке (Help) программного продукта.
2.2. Параметры команд отладчика.
Запуск отладчика возможен в двух вариантах:
1) D:USER> debug
2) D:USER> debug <имя файла>
При втором варианте запуска отладчик загружает содержимое файла в нижний доступный сегмент (при этом файл с расширением .com загружается в этом сегменте со смещением 100h).
После запуска debug на выполнение пользователь получает приглашение (-) и может вводить команды. Формат команды:
буква [параметр(ы)] Здесь буква — первая буква команды, например ко-манда F — (Fill —заполнять). параметр(ы) — перечень параметров, которые могут быть разделены пробелами или запятыми. Разделитель обязателен между последовательностью шестнадцатеричных величин. Буквы могут быть пропис-ными и строчными.
Перечислим типы параметров: величина — от одной до четырех шестна-дцатеричных цифр (суффикс h не указывается); байт — две шестнадцатерич-ные цифры; адрес — можно задать тремя способами:
1) сегмент:смещение, например, 057D:0020, или 57D:20 (ведущие нули можно не указывать);
2) сегментный регистр:смещение, например, cs:109
3) смещение. Если команда работает с машинными инструкциями (команды A,G,L,T,U,W), подразумевается сегментный регистр CS, если работа идет с данными — DS.
область — диапазон адресов; его можно задать двумя способами
1) адрес смещение, например, cs:100 110 (Неверно: cs:100 cs:110 — второй параметр не является смещением).
2) адресLвеличина, где величина — размер области в байтах, например cs:100L11 задает точно такую же область длиной 17 байтов, как и в предыду-щем примере.
строка — цепочка символов, заключенная в одинарные или двойные ка-вычки (если кавычки встречаются внутри строки, их следует удваивать).
Примеры: Эта строка правильная
"this ""string"" is okay"
список — последовательность байтов и/или строк.
пример: "Hello!",d,a,$
3.3. Команды отладчика
Сгруппируем команды по их функциональному назначению.
1) Работа с данными.
1.1) D [область] Dump — дамп
Эта команда бала разобрана ранее.
1.2) E адрес [список] Enter — ввод
Ввод данных по указанному адресу.
а) E адрес (список опущен)
-e200
1C36:0200 01.02 12. 1B.0
вводим пробел для перехода к следующему байту
Результат:
-d200L3
1C36:0200 02 12 00
Итак, при нажатии пробельной клавиши отладчик выводит очередной байт и запрашивает его изменение, выводя точку. Для перехода к предыдущему бай-ту нужно ввести дефис (попробуйте!).
Упражнение. С помощью команды E можно просматривать память. По-смотрите, что будет происходить, если вы подадите команду efff0 и несколь-ко раз нажмете пробельную клавишу. Перейдете ли Вы границу сегмента? А что произойдет, если вы наберете команду dfff0?
б) E адрес список
e200 02 12 00
Результат тот же, что и в предыдущем примере, но на этот раз замена дан-ных ведется "вслепую".
Слова приходится заносить в память побайтно. Байты заносятся в обратном порядке. Например, для ввода по адресу (смещению) 120 слова 1234 подаем команду:
-e120 34 12
Пример ввода строки символов:
-e130 string for example,D,A,$
(0Dh — код возврата каретки, 0Ah — код перевода строки. $ — терминатор (ограничитель) строки, который нужен при использовании системной функции вывода строки на экран. Эту функцию мы изучим позднее.)
1.3) R [имя регистра] Register — регистр
а) R (без параметра) — выводятся имена всех регистров и их содержимое. Последняя строка вывода имеет формат:
адрес код команды мнемоника команды [содержимое памяти]
1С36:0100 A10002 MOV AX,[0200] DS:0200=01E4
б) R имя регистра — debug выводит содержимое регистра, а на следую-щей строке помещает двоеточие — приглашение к вводу нового значения. К сожалению, можно указывать только 16-разрядные регистры.
-rbx
1107
: 1 (вводим новое содержимое регистра)
<Enter>
-rah
br ERROR (недопустимое имя регистра)
в) RF выводит содержимое регистра флагов
NV UP DI NG NZ AC PE NC -
После дефиса можно ввести новые значения флагов: - PLCY (если задано более чем один код значения для флага, появляется сообщение об ошибке df error если задан код значения, отсутствующий в списке — сообщение bf error).
1.4) F область список Fill—заполнение
Если размер области превосходит длину списка, то список используется повторно, пока область не будет заполнена. Остаток списка усекается.
Пример. Перед созданием программы в отладчике полезно заполнить уча-сток памяти кодом команды nop (90h) (если это не сделать, "мусор" в памяти сбивает с толку начинающего пользователя).
-f100L100 90
Упражнение. Выполнить f400L10 1 2 3 и изучить результат.
2) Работа с кодами команд.
2.1) A [адрес] Assemble — ассемблировать
Пример работы этой команды мы уже видели. Если в начале сеанса работы с debug не указывать адрес, то ассемблирование начнется с адреса XXXX:0100.
Отметим, что с использованием мини-ассемблера заполнение памяти дан-ными осуществить даже проще, чем с помощью команды E:
-a200
1C36:0200 dw ffd0,12,a1c7
1C36:0206
-
(В результате [200]=FFD0h, [202]=0012h, [204]=A1C7h.)
-a200
1C36:0200 db "String",D,A,$
1C36:0209
Здесь использованы директивы dw (Define Word — задать слово) и db (Define Byte — задать байт).
2.2) U [область] Unassemble — дисассемблировать
Команда переводит коды из области памяти в мнемонику команд.
Если перевод невозможен, то выводится ???? или DB число. Если параметр область опущен, то команда дисассемблирует 20 байт, начиная с текущего значения IP. Вновь введем U — следующие 20 байт и т.д. (аналогично команде D без параметров).
3) Выполнение программы.
3.1) T[=стартовый адрес] [количество повторений] Trace — трассировка
После выполнения каждой команды выводится информация, как при пода-че команды R. Приведем примеры:
а) t — выполнить одну команду, адрес которой в CS:IP;
б) t5 — выполнить 5 команд, начиная с текущего адреса;
в) t=106 8 — выполнить 8 команд, начиная с адреса CS:106.
3.2) G[=стартовый адрес] [адрес останова] Go — прогон
а) g — выполнить программу, начиная с адреса, хранящегося в IP. Про-грамма должна заканчиваться инструкциями завершения (эти инструкции мы изучим позднее — сейчас упоминаем о них только в справочных целях), на-пример, INT 20h или MOV AH,4Ch /INT 21h. После выполнения INT 20h debug выводит сообщение:
Program terminated normally (Выполнение программы завершено) Теперь повторный запуск программы возможен только после выполнения команды L (см. ниже).
б) g=100 адрес команды nop
Мы рекомендуем на начальном этапе обучения завершать учебные про-граммы, набираемые в debug, командой nop и использовать ее адрес в качестве адреса останова.
4) Работа с файлами и дисками.
4.1) N имя файла Name — имя
Задание имени файла. Расширение указывать обязательно. Используется перед следующими двумя командами.
4.2) L [адрес] Load — загрузка
Содержимое файла переписывается в ОЗУ. Файлы с любым расширением кроме .exe — начиная с указанного адреса (если адрес опущен, то начиная с CS:0100). Для файлов с расширением .exe адрес игнорируется, используется стартовый адрес, записанный в самом файле.
По окончании загрузки в BX:CX содержится размер файла в байтах.
4.3) W [адрес] Write — запись
Запись файла на диск. Предварительно в BX:CX нужно записать размер файла. Если адрес не указан, то подразумевается CS:0100.
У команд L и W имеются также параметры для работы с секторами диска. Мы их не рассматриваем.
5) Сервис.
5.1) H <величина> <величина> Hex — шестнадцатеричный
Встроенный калькулятор. Вычисляет сумму и разность указанных величин:
H a b (a и b — слова)
a+b a-b
Примеры: 1) Программа начинается по адресу 0100h и заканчивается по ад-ресу 012Ah. Определить размер программы.
-h12a ff
0229 002B (Размер программы 2Bh)
2) В байте записано число FEh. Дополнительным кодом какого числа оно явля-ется? Расширяем знак до размеров слова
-H0 fffe
fffe 0002 (Дополнительный код ¬–2 есть FEh)
5.2) M область-источник адрес_приемника Move — перемещать
Пример. Предположим, мы набрали программу
-a100
11CF:0100 mov ax,1
11CF:0103 add ax,bx
11CF:0105 nop
11CF:0106
и обнаружили, что пропустили команду mov bx,2. Перемещаем часть про-граммы "подальше". Размер области берем "с запасом".
-m103L20 200
Вводим недостающую команду
-a103
11CF:0103 mov bx,2
11CF:0106
Теперь мы знаем адрес назначения (0106) и перемещаем хвост программы
-m200L20 106
-u100 (проверяем правильность результата) ...
Упражнение. Разработайте последовательность действий, если нужно уда-лить часть команд программы. О "перекрытии" области-приемника и области-источника беспокоиться не нужно (проверьте!).
5.3) C область1 адрес_области Compare — сравнение
Выводится таблица в формате
адрес1 байт1 байт2 адрес2
в том случае, если байт1 не совпадает с байт2.
Упражнение. Придумайте пример. С помощью команды E введите данные в две области памяти (например, две незначительно различающиеся строки) и сравните содержимое областей с помощью команды C.
5.4) S область список Search — поиск
Список — это список байтов или строка. Debug выдает все адреса байтов или строк, которые совпадают с указанными.
Упражнение. Придумайте примеры.
6) Остальные команды.
6.1) Q Quit — завершение
Осуществляется выход из debug. При этом набранные программы и данные теряются, если они предварительно не были сохранены посредством команды W.
6.2) ? Выводит на экран алфавитный список команд debug.
3.5. Как получить текст программы, набранной в debug.
После отладки внесения необходимых изменений в команды программы хотелось бы получить файл с текстом программы, чтобы добавить в него ком-ментарии, распечатать и т.д. Можно рекомендовать следующую последова-тельность действий.
1) Определяем размер программного кода. Если вся программа состоит из чистого кода, как pr1.com, даем команды
D:USER>debug pr1.com
-r
и читаем в регистрах BX:CX шестнадцатеричный размер программы. (В нашем случае 9h).
2) Создадим с помощью любого текстового редактора файл (например, pr1.cmd), содержащий команды отладчика:
U100L9
Q
(последнюю команду Q обязательно завершить нажатием Enter). Вновь запуска-ем debug.
D:USER>debug pr1.com < pr1.cmd > pr1.txt
Входная информация поступает из pr1.cmd, выходная направляется в файл pr1.txt. Для этого используются символы > и < (перенаправление операций ввод-вывода).
Остается подправить содержимое файла pr1.txt в редакторе.
Упражнение. В предыдущей главе мы выясняли, какие флаги состояния будут выставлены центральным процессором при выполнении сложения слов: 2345h + 3219h и 5439h + 456Ah. Проверить правильность сделанных выводов, используя debug.
2. Отладчик Debug 2.1. Пример работы с отладчиком
Лекции по предмету «Информатика»