Справка по команде debug и ее параметрам

Привет, юный хакер! Ты уже многое знаешь, но крутой хакер никогда не останавливается на достигнутом. Эта статья посвящена работе с стандартным дебаггером системы ДОС. Ты скажешь: «На кой фиг мне это надо мне, крутому перцу?».
Представь ситуацию: ты приходишь в компьютерный клуб (интернет-кафе, к другу домой), а там на тачке дисководы сняты, сидюки заклеены, а пакость сделать все же хочется. Естественно, на любом «нормальном» компе нет никаких компиляторов С, ассемблеров… но почти на каждом «нормальном» компе есть ДОС! Да, именно ДОС, и его последователи — Винды всех типов а конкретнее программа
DEBUG.

Как? Набрать короткую (если времени мало, да и сил жалко), но неприятную программку, сохранить ее на диске и потом запустить, получив моральное удовлетворение. Посмотрим, как это делается, но для начала изучим несколько простых, но весьма полезных команд.

Итак, вы запустили программу DEBUG

Первая команда –D (dump) .

Эта команда позволяет просмотреть некоторую область памяти, адрес которой задан в параметре в формате сегмент:смещение.

Для начала посмотрим ПЗУ BIOS:

Здесь вы видите фирму-производителя вашей
BIOS. А по адресу:

получаем интересную информацию о системе,
такую как дата создания БИОС, чипсет… А по данному адресу
(0000:046C) находится таймер БИОС. Отчетливо видно, что значения все время меняются.
Для программиста удобно просматривать сегменты команд, данных и стека (CS, DS и SS, соответственно).

Выше мы видим содержимое сегмента данных, т. е.
значения определенных переменных.

А тут представлено содержимое сегмента команд, т.е. машинные коды команд, готовых к исполнению.
Освоив команды просмотра памяти, впоследствии мы сможем эффективно отлаживать наши программы и просматривать введенный нами код перед исполнением (для нас сейчас это приоритетная задача).

Еще одна важная команда -R (register) , позволяющая просматривать состояние конкретного регистра и изменять его состояние или же сразу перейти к первой выполняемой команде с просмотром всех регистров.

AX 1203
: 0

В данном фрагменте мы просматриваем регистр АХ и очищаем его (пишем в него 0).
Чтобы перейти к первой выполняемой команде (по адресу CS:100):

AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000
SI=0000 DI=0000
DS=3B9A ES=3B9A SS=3B9A CS=3B9A IP=0100 NV UP EI PL NZ NA PO NC
3B9A:0100 E82421 CALL 2227

Третья команда –E (enter) Addres .

Предназначена она для изменения значений в
памяти – с помощью нее можно уже вводить команды в машинных кодах. Замечание: при вводе данных сначала пишется младший байт
(по младшему адресу), затем – старший (по старшему), т. е.
чтобы записать по адресу DS:0000 число 1234h необходимо ввести:

E DS:0000 34 12

Например введем следующее:

E cs:100 B8 34 12
-D CS:100

А с помощью команды U (unassemble) , дизассемблируем введенные команды и получим:
-U CS:100,102
3B9A:0100 B83412 MOV AX,1234

Таким же образом можно дизассемблировать любой участок памяти, что очень полезно.
Но вместо ввода команд на машинном языке, можно воспользоваться встроенным
ассемблером программы DEBUG. Для этого существует команда
-A (assemble) . С помощью этой команды вы можете написать уже нормальную программку на ассемблере, выполняющую необходимые действия.:

A
0B3B:0100 mov ax,1234
0B3B:0103 mov ah, 4c
0B3B:0105 int 21
0B3B:0107

Затем в регистр СХ необходимо поместить размер программы в байтах. Он будет равен разности конечного и начального смещений. Теперь остается только осуществить запись на диск командой W и в результате увидеть записанное количество байтов. В итоге мы получаем программу, готовую к исполнению. Выход осуществляется командой q. Пример:

A
0B3B:0100 mov ax,1234
0B3B:0103 mov ah, 4c
0B3B:0105 int 21
0B3B:0107
-u CS:100, 106
0B3B:0103 B44C MOV AH,4C
0B3B:0105 CD21 INT 21
-r cx
CX 0000
:7
-r
AX=0000 BX=0000 CX=0007 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0B3B ES=0B3B SS=0B3B CS=0B3B IP=0100 NV UP EI PL NZ NA PO NC
0B3B:0100 B83412 MOV AX,1234
-N my.com
-W
Запись 00007 байт
-q

В заключение можно сказать, что данный способ создания программ открывает новые возможности для любителей компьютерных пакостей, приколов, да и просто программистов-любителей – ведь теперь для создания небольших программ, вместо установки компиляторов, можно воспользоваться стандартными средствами системы, а DEBUG входит в поставку во все Винды вплоть до ХР. Я думаю, что это поможет вам веселее провести время за чужим компом, вызывая истинное удивление хозяина (дисков и дискет-то вы не приносили!!!) новыми эффектами работы его оборудования. Успехов, юные любители хакерного экстрима!



Программа DEBUG (отладчик) дает средство обнаружения ошибок при
работе с программой, транслированной в машинный язык. Программа
DEBUG обеспечивает возможность пошагово выполнять программу и
следить за тем, что при этом происходит. Программа DEBUG - это еще
одно программное средство, поставляемое как часть DOS. Вы
загружаете ее так же, как и любую другую программу, и работаете в
диалоге, используя клавиатуру и экран. Когда программа DEBUG
ожидает каких-либо действий со стороны пользователя, то свой запрос
она обозначает символом "-".

Вместо перечисления всех команд, которые входят в программу
DEBUG, используем данный отладчик для проверки работы только что
составленной программы, приведенной на Фиг. 5.13 и П5.14. На
Фиг. 5.17 приведен соответствующий листинг.
В данном примере сначала вызывается программа DEBUG и
указывается та программа, которую предполагается отлаживать - в
нашем случае программа FIG5=13.EXE. После того, как программа DEBUG
загружена, она производит загрузку отлаживаемой программы.
Управление теперь принадлежит отладчику, и он с помощью символа "-"
показывает, что ожидает ввода. До тех пор, пока вы не введете для
него указаний, с программой ничего происходить не будет.

Команда R выводит содержимое всех регистров в момент,
соответствующий загрузке программы FIG5=13 и передаче ей управления.
Содержимое регистров не требует пояснений, за исключением, быть
может, значений флагов. Флаг NV указывает на отсутствие
переполнения, флаг UP - флаг направления и т.д. При выводе
содержимого регистров в последней строке приводится следующая
выполняемая команда. В ячейке 04C5:0000 записана команда PUSH DS.
B>A:DEBUG FIG5_13.EXE
-R

AX=0000 BX=0000 CX=0120 DX=0000 SP=FFF0 BP=0000 SI=0000 DI=0000
DS=2C26 ES=2C26 SS=2C26 CS=2C26 IP=0000 NV UP DI PL NZ NA PO NC
2C26:0000 1E PUSH DS

2C26:0000 1E PUSH DS
2C26:0001 B80000 MOV AX,0000
2C26:0004 50 PUSH AX
2C26:0005 FC CLD
2C26:0006 8CC8 MOV AX,CS
2C26:0008 8ED8 MOV DS,AX
2C26:000A 8D361D00 LEA SI,
2C26:000E AC LODSB
2C26:000F A24000 MOV ,AL
2C26:0012 E82C00 CALL 0041
2C26:0015 803E40000A CMP ,0A
2C26:001A 75F2 JNZ 000E
2C26:001C CB RET Far
2C26:001D 9D POPF
2C26:001E E2A0 LOOP FFC0
2C26:0020 20AFE0AE AND ,CH
2C26:0024 A3E0A0 MOV ,AX

D2C26:0

2C0E:0000 CD 20 00 A0 00 9A EE FE 1D F0 ED 04 04 1C 3C 01 . ............<.
2C0E:0010 22 1B EB 04 22 1B 04 1C 01 01 01 00 02 06 FF FF "..."...........
2C0E:0020 FF FF FF FF FF FF FF FF FF FF FF FF 08 2C D0 FF .............,..
2C0E:0030 04 1C 14 00 18 00 0E 2C FF FF FF FF 00 00 00 00 .......,........
2C0E:0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
2C0E:0050 CD 21 CB 00 00 00 00 00 00 00 00 00 00 20 20 20 .!...........
2C0E:0060 20 20 20 20 20 20 20 20 00 00 00 00 00 20 20 20 .....
2C0E:0070 20 20 20 20 20 20 20 20 00 00 00 00 00 00 00 00 ........

RAX
AX 0000
:1234

E 2C0E:21
2C0E:0021 69. 73. 20. 61.20 20.


DS=2C26 ES=2C26 SS=2C26 CS=2C26 IP=003C NV UP DI PL NZ NA PO NC
2C26:003C CD10 INT 10
-T

AX=0E54 BX=0000 CX=003F DX=0000 SP=FFEA BP=0000 SI=001D DI=0000
DS=2C26 ES=2C26 SS=2C26 CS=F000 IP=0165 NV UP DI PL NZ NA PO NC
F000:F065 FB STI
-T

Фиг. 5.17 Листинг отладчика для Фиг 5.13 и 4.14 (начало)
AX=0E54 BX=0000 CX=003F DX=0000 SP=FFEA BP=0000 SI=001D DI=0000
DS=2C26 ES=2C26 SS=2C26 CS=F000 IP=0166 NV UP DI PL NZ NA PE NC
F000:F066 FC CLD
-G 2C26:3E

T
AX=0E54 BX=0000 CX=003F DX=0000 SP=FFEA BP=0000 SI=001D DI=0000
DS=2C26 ES=2C26 SS=2C26 CS=2C26 IP=013E NV UP DI PL NZ NA PO NC
2C26:003E RET
-G

Эта программа - тест

Program terminated normally
-R

AX=0754 BX=0000 CX=003F DX=0000 SP=FFEA BP=0000 SI=001D DI=0000
DS=2C26 ES=2C26 SS=2C26 CS=2C26 IP=003E NV UP DI PL NZ NA PO NC
2C26:003E C3 RET
-Q

Фиг. 5.17 Листинг отладчика для Фиг 5.13 и 4.14 (продолжение)

Здесь следует немного задержаться и проанализировать
информацию, которая записывается в регистры. Содержимое регистров
соответствует моменту, когда программа FIG5=13 получает управление
от командного процессора. Обратите внимание, что пара регистров
CS:IP указывает на первую команду, определяемую оператором END
программы. Регистры DS и ES указывают на префикс программного
сегмента. И наконец, пара регистров SS:SP указывает на сегмент
STACK. Описанное состояние регистров будет сравниваться позднее с
аналогичным состоянием регистров для файла типа.COM.

Чтобы просмотреть большее число команд, надо ввести символ "U"
(дизассемблировать), и на дисплей выводится около двадцати
следующих команд. Это удобно при обладке программы, для которой нет
листинга. Дизассемблирование программы позволяет просмотреть ее
команды. Это может сэкономить вам бумагу и время в случае, когда в
программу внесены небольшие изменения. Так как ваш листинг больше
не соответствует той программе, которая находится в памяти, то ее
дизассемблирование позволяет вам узнать правильные адреса для
каждой команды.

Однако у дизассемблирования с помощью программы DEBUG имеется
ряд недостатков по сравнению с использованием листинга. Отсутствуют
комментарии (может быть очень важные для понимания программы), и
ячейки памяти идентифицируются только по адресу, а не по имени
переменной. Например, хранящаяся в ячейке 04C5:000E команда имеет,
как показано на Фиг.5.13, следующий вид:

MOV OUTPUT_CHARACTER,AL

А в дизассемблированном виде

MOV ,AL

Это одна и та же команда. Для программиста, выполняющего
отладку, имя переменной OUTPUT_CHARACTER говорит больше, чем адрес
ячейки . Однако программе DEBUG не известны имена переменных,
и она вынуждена оперировать фактическими адресами.

Кроме того, программа, DEBUG не обеспечивает той же самой
ассемблерной мнемоники, которую воспринимает ассемблер. Это значит,
что некоторые команды будут выглядеть по-разному. Команда из ячейки
04C5:0014 будет при дмзассемблировании иметь вид

CMP B,,0A

Но та же саммая команда на Фиг.5.13 представлена в виде:

CMP OUTPUT_CHARACTER,10

Программа дизассемблирования как на входе, так и на выходе
работает только с шестнадцатеричными значениями. Этим объясняется
появление значения 0A. Мы уже выяснили, почему получается значение
, вместо имени OUTPUT_CHARACTER. Что же такое символ "B,"?

Ассемблер оперирует переменными вполне определенного типа. Это
значит, что во время ассемблирования тип переменных может иметь
значение: байт, слово или какой-нибудь другой. Таким образом, когда
программист вводит команду, содержащую ссылку на область памяти, то
ассемблеру известен размер этой области. На программа DEBUG не
имеет представления о длине переменной, записанной по адресу
. Однако программе дизассемблирования точно известно, что
данная команда пересылает ровно один байт данных, указанных
непосредственно в команде, по адресу . Таким образом, символ
"B," указывает на то, что непосредственная операция состоит в
пересылке одного байта. Для получения того же самого результата с
помощью ассемблера соответствующая команда должна иметь вид:

CMP BYTE PTR ,10

Вы можете рассматривать символ "B," как сокращение BYTE PTR.
Аналогично символ W используется для WORD PTR,L - для длинного
(far) возврата и т.д.

Вместе с командой в дизассемблированном виде вводится и ее
объектный код. Как вы можете заметить, по адресу 04C5:001C записаны
какие-то команды, которых нет на Фиг. 5.13. Эта область данных,
содержащая строку "Это тест". Однако команде, осуществляющей
дизассемблирование, не известно, где в программе кончаются команды
и начинаются данные. Таким образом она все интерпретирует как
команды. (Кстати, именно эта последовательность команд выполнялась
бы, если в вашей программе был сделан переход в рассматриваемую
область данных.)

Команда вывода на экран D позволяет просмотреть на дисплее
области данных. Отображение на экране состоит из двух частей.
Вместе с листингом содержимого ячеек памяти в шестнадцатеричном
представлении приводятся символы в коде ASCII, которые
соответствуют этим значениям. Если отображение команд подобным
образом не имеет смысла, то область данных представляется очень
ясно. Когда вам будет нечем особенно заняться, вы можете
попробовать написать такую программу, команды которой в коде ASCII
соответствуют инициалам вашего имени. С помощью отладчика можно
изменять содержимое регистров и ячеек памяти. Если ввести символ R
(регистр) и затем тип регистра, то на дисплей будет выведено
содержимое этого регистра с возможностью его коррекции. Если нажать
клавишу "возврат", то содержимое регистра останется прежним. Оно
будет изменено, если ввести новое значение.

Можно также модифицировать содержимое ячеек памяти. Ввод
символа E (редактирование) позволяет это сделать. При этом
программа DEBUG выводит на дисплей значения отдельных ячеек памяти,
после которых следует символ. Вы можете изменить содержимое
ячейки, вводя новое значение, либо нажать клавишу пробела, чтобы
перейти к следующей ячейке, или - клавишу "возврат", чтобы
вернуться к режиму запроса следующей команды отладчика. В
рассматриваемом примере значения в первых трех ячейках остаются
прежними. Содержимое ячейки 04C5:0024 изменено со значения 61H на
значенее 20H. Так как эта ячейка входит в область данных, то
выводимое сообщение будет отличаться от тог, которое было в
транслированной программе.

В любой команде, обращающейся к ячейкам памяти, предполагается,
что адрес является частью команды. Команда E, как и команда
отображения, выводит на дисплей содержимое ячейки по указанному в
ней адресу. Точно так же можно было использовать адрес в команде
дизассемблирования. Можно ввести адрес в виде сегмента и смещения,
или только смещения. Если вы указали только смещение, то
соответствующий сегментный регистр будет выбран программой DEBUG. В
случае команды U используется регистр CS, а для команд D и E по
умолчанию сегмент будет определяться регистром DS.

Теперь попытаемся выполнить эту программу. Ее можно просто
запустить и посмотреть, что будет происходить. На для этого не
нужна программа DEBUG. Программа DEBUG позволяет задать точки
останова, называемые "точками прерывания" программы. Благодаря
введению в программу таких точек можно возвращать управление
программе DEBUG. Это дает еще одну возможность проверки состояния
памяти и регистров для того, чтобы контролировать ход выполнения
программы.

Команда G, (выполнять) передает управление от программы DEBUG
пользовательской программе. Выполнение команд начинается с ячейки,
задаваемой парой регистров CS:IP (так же, как в реальном
микропроцессоре). Тестируемая программа продолжает выполняться до
тех пор, пока она не пройдет точку прерывания. В нашем примере мы
задали точку прерывания по адресу 3CH. Так как мы указали только
смещение, то для определения сегмента программа DEBUG использует
содержимое регистра CS. Из листинга, приведенного на Фиг. 5.14,
видно, что смещение 3CH соответствует команде INT 10H. В
рассматриваемом примере программы было выбрано именно это место,
потому что это - та точка, где управление передается подпрограмме
BIOS, вызываемой из ПЗУ. Проверка программы в этой точке
гарантирует, что мя установили регистры в нужное состояние перед
выполнением подпрограммы BIOS.

Как только встречается точка прерывания, управление
возвращается программе DEBUG. При этом, так же как и в случае
команды R, на дисплей выводятся содержимое регистров и следующая
выполняемая команда. Так как управление опять передано программе
DEBUG, вы можете использовать любую из команд отладки.

Имеются ограничения на использование точек прерывания.
Фактически точка прерывания реализуется кодом операции 0CCH.
Соответствующая этому коду команда вызывает прерывание INT 3.
Данное математическое прерывание возвращает управление программе
DEBUG. Если какая-то команда возвращает управление отладчику, то
точка прерывания должна находиться в начале этой команды. Если же
точка прерывания выбрана где-то в другом месте, то управление не
будет возвращено отладчику и будет выполняться не та команда
программы, которая предполагалась. Например, если бы было задано
"=G 3D", то по адресу 3CH была бы команда INT 0CCH, и дальнейшее
выполнение программы предсказать трудно.

Если точка прерывания выбрана осмотрительно, то никаких
осложнений не будет. Командв "G" позволяет задать до десяти точек
прерывания. После прохождения любой из них происходит
восстановление исходных значений точек прерывания. Выполнение
команды отладки "G" без указания точек прерывания никогда не выйдет
ни на какую из ранее заданных точек прерывания, потому что все они
были удалены. Если вы запустили программу, и произошел ее останов и
она зациклилась, то возможно, что вернуть управление, которое
передано программе, удастся только с помощью клавиши системного
сброса Ctrl=Alt=Del, т.е. вам придется начать все с начала.
Запуская незнакомую программу, следует быть осторожным.

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

Существует еще одно обстоятельство, связанное с точками
прерывания, о котором следует помнить. Если вы попытаетесь задать
точку прерывания в области, относящейся к ПЗУ, то ничего не
получится. Так как вы не можете менять содержимое ПЗУ, то команда
0CCH никогда туда не запишется.

Рассмотрим следующую команду отладчика - команда трассировки T.
Данная команда инициирует выполнение одной команды отлаженной
программы. В нашем примере команда T выполнена несколько раз. Как
вы можете убедиться, выполняется несколько первых команд BIOS,
вызванной по прерыванию INT 10H. Подпрограмма BIOS, естественно,
находится в ПЗУ. Команда трассировки позволяет "приостановить"
программу при ее выполнении в ПЗУ.

Перед передачей управления пользовательской программе команда
трассировки выставляет в регистре флагов соответствующий бит
трассировки. Этот бит инициирует прерывание INT 1 после выполнения
каждой команды. Вектор прерывания INT 1 возвращает управление
программе DEBUG. Выполнение прерывания INT 1 автоматически
сбрасывает бит трассировки в исходное состояние. Это значит, что
программа DEBUG не прерывается после выполнения каждой ее команды.
Команда трассировки служит прекрасным средством "пробиться" через
трудный участок программы. При этом программа DEBUG выводит на
экран каждую команду вместе с содержимым регистров как раз в
момент, предшествующий выполнению этой команды. Так как в данном
режиме используются не точки прерывания, а собственно прерывания,
то можно выполнять трассировку даже программ ПЗУ.

Вернемся к нашему примеру. Команда =G 4C5:3E обеспечивает
полное выполнение подпрограммы BIOS. Обратите внимание, что
программа вывела на дисплей символ "Э". Вызванная по прерыванию 10H
подпрограмма BIOS выводит символы на дисплей. В данном случае это
первый символ выводимого сообщения. Так как теперь можно быть
уверенными, что наша программа выполняется правильно, то, введя
символ "G", мы обеспечим выполнение программы до конца без точек
прерывания.

В данном примере рассматривался файл типа.EXE, и потому для
возврата управления системе DOS мы не могли использовать прерывание
INT 20H. Вместо этого программа записала в стек состояние регистра
DS и значение 0. Управление передается обратно системе DOS в конце
основной программы с помощью команды возврата типа FAR. Программа
DEBUG распознает это и фиксирует состояние машины в конце
тестируемой программы. Если бы это был файл типа.EXE, то
прерывание INT 20H аналогичным образом вернуло бы управление
программе DEBUG. Теперь, уделив достаточно времени этому примеру,
мы можем выйти из программы DEBUG и вернуться в систему DOS с
помощью команды завершения Q.

Использование стандартного отладчика debug.exe

Сегодня мы рассмотрим стандартный отладчик debug.exe , входящий в любую версию DOS/Windows. Должен заметить, что этот отладчик не такой мощный, как гиганты SoftICE или Turbo Debugger. Однако, в то же время debug.exe очень прост и доступен, и просто идеально подходит для начинающих программистов на языке Ассемблер.
Итак, запускаем debug.exe (для этого заходим в Пуск->Выполнить и выполняем команду debug ) и начинаем изучать этот замечательный отладчик

Команды debug.exe

Для начала разберемся с правилами набора команд debug.exe :

· В debug.exe не различается регистр букв.

· Пробелы в командах используется только для разделения параметров.

· Вводимые числа должны быть в шестнадцатеричной системе счисления, причем без завершающей буквы h .

· Сегмент и смещение записываются с использованием двоеточия, в формате сегмент:смещение , например, CS:3C1 (смещение 3C1h в сегменте кода) или 40:17 (смещение 17h в сегменте, адрес начала которого - 40h ).

Разобравшись с правилами, давайте перейдем к изучению команд debug.exe . Замечу, что работа с командами debug.exe в чем-то похожа на работу с командной строкой DOS. Поcле загрузки отладчика на экране появится приглашение, выглядещее в виде дефиса:

Регистры CS , DS , ES , SS в этот момент инициализированы адресом 256-байтного префикса сегмента програмы , а рабочая области в памяти будет начинаться с адреса этого префикса + 100h .
Команды debug.exe вводятся сразу после приглашения на месте, которое отмечено курсором. Каждая команда состоит из идентификатора и параметров, идентификатор состоит из одной буквы.

Краткая таблица всех команд debug.exe

Команда Описание Формат
A (Assemble) Транслирование команд ассемблера в машинный код; адрес по умолчанию - CS:0100h. A [<адрес_начала_кода>]
C (Compare) Сравнение содержимого двух областей памяти; по умолчанию используется DS. В команде указывается либо длина участков, либо диапазон адресов. C <начальный_адрес_1> L<длина> <начальный_адрес_2> C <начальный_адрес_1> <конечный_адрес_1> <начальный_адрес_2>
D (Display/Dump) Вывод содержимого области памяти в шестнадцатеричном и ASCII-форматах. По умолчанию используется DS; можно указывать длину или диапазон. D [<начальный_адрес> ] D [начальный_адрес конечный_адрес]
E (Enter) Ввод в память данные или инструкции машинного кода; по умолчанию используется DS. E [<адрес> [<инструкции/данные>]]
F (Fill) Заполнение области памяти данными из списка; по умолчанию используется DS. Использовать можно как длину, так и диапазон. F <начальный_адрес_1> L<длина> "<данные>" F <начальный_адрес> <конечный_адрес> "<данные>"
G (Go) Выполнение отлаженной программы на машинном языке до указанной точки останова; по умолчанию используется CS. При этом убедитесь, что IP содержит корректный адрес. G [=<начальный_адрес>] <адрес_останова> [<адрес_останова> ...]
H (Hexadecimal) Вычисление суммы и разности двух шестнадцатеричных величин. H <величина_1> <величина_2>
I (Input) Считывание и вывод одного байта из порта. I <адрес_порта>
L (Load) Загрузка файла или данных из секторов диска в память; по умолчанию - CS:100h. Файл можно указать с помощью команды N или аргумента при запуске debug.exe. L [<адрес_в_памяти_для_загрузки>] L [<адрес_в_памяти_для_загрузки> [<номер_диска> <начальный_сектор> <количество_секторов>]]
M (Move) Копирование содержимого ячеек памяти; по умолчанию используется DS. Можно указывать как длину, так и диапазон. M <начальный_адрес> L<длина> <адрес_назначения> M <начальный_адрес> <конечный_адрес> <адрес_назначения>
N (Name) Указание имени файла для команд L и W. N <имя_файла>
O (Output) Отсылка байта в порт. O <адрес_порта> <байт>
P (Proceed) Выполнение инструкций CALL, LOOP, INT или повторяемой строковой инструкции с префиксами REPnn, переходя к следующей инструкции. P [=<адрес_начала>] [<количество_инструкций>]
Q (Quit) Завершение работы debug.exe. Q
R (Register) Вывод содержимого регистров и следующей инструкции. R <имя_регистра>
S (Search) Поиск в памяти символов из списка; по умолчанию используется DS. Можно указывать как длину, так и диапазон. S <начальный_адрес> L<длина> "<данные>" S <начальный_адрес> <конечный_адрес> "<данные>"
T (Trace) Пошаговое выполнение программы. Как и в команде P, по умолчанию используется пара CS:IP. Замечу, что для выполнения прерываний лучше пользоваться командой P. T [=<адрес_начала>] [<количество_выполняемых_команд>]
U (Unassemble) Дизассемблирование машинного кода; по умолчанию используется пара CS:IP. К сожалению, debug.exe некорректно дизассемблирует специфические команды процессоров 80286+, хотя они все равно выполняются корректно. U [<начальный_адрес>] U [<начальный_адрес конечный_адрес>]
W (Write) Запись файла из debug.exe; необходимо обязательно задать имя файла командой N, если он не был загружен. А программы записываются только в виде файлов.COM! W [<адрес> [<номер_диска> <начальный_сектор> <количество_секторов>]]

Примечание. Символами отмечены необязательные параметры.

Просмотр областей памяти

В этой части нашей статьи мы рассмотрим подробно работу команды D , позволяющей просматривать содержимое отдельных областей памяти.
Этот пример использует команду D для просмотра области памяти, начиная с 0159:0240 :

0159:0240 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ..........l.....

0159:0250 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

0159:0260 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

0159:0270 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

0159:0280 00 00 00 00 00 00 00 00-00 FF FF FF FF 00 00 00 ................

0159:0290 FF 00 00 00 00 00 00 00-00 00 4E 4F 20 4E 41 4D ..........NO NAM

0159:02A0 45 20 20 20 20 00 26 81-4F 03 00 01 CB 00 00 00 E .&.O.......

0159:02B0 00 00 00 00 00 00 00 00-00 00 00 01 07 04 FF 02 ................

Здесь на запрос просмотра участка памяти мы получили восемь строк, в которых указано содержимое выбранной области памяти. Каждая строка состоит из трех частей:

· Адрес первого слева показанного байта в формате сегмент:смещение .

· Шестнадцатеричное представление параграфа (16 байт), начинающегося с указанного в начале строки байта.

· Символы этого же параграфа в ASCII-формате.

Адрес, указанный в строке, относится исключительно к первому байту в параграфе, а адреса последующих байтов следует вычислять самостоятельно. Шестнадцатеричное представление содержит по два знака в каждом байте, а сами байты разделены пробелами для облегчения чтения. Кроме того, следует отметить, что восьмой и девятый байты разделены дефисом, разделяя тем самым параграф на две части и облегяая вычисление адресов байтов в параграфе.

Итог

А теперь, после небольшого обзора возможностей стандартного отладчика debug.exe давайте подведем итоги. Итак:

· debug.exe можно применять для наблюдений и отладки программ на ассемблере и машинных кодах.

· debug.exe позволяет трассировать программу, устанавливать точки останова, просматривать области памяти, вводить программы непосредственно в память компьютера.

· debug.exe представляет загружаемые программы как программы .COM .

· debug.exe воспринимает только числа в шестнадцатеричной системе.

· debug.exe не различает регистр букв.

Лабораторная работа № 1

Тема : «Отладчик DEBUG ».

Краткая аннотация : данная работа посвящена знакомству с отладчиком DEBUG, который позволяет:

  • набирать небольшие фрагменты ассемблерного кода;
  • выполнять трассировку фрагментов кода;
  • отслеживать состояние регистров процессора и ячеек оперативной памяти в процессе трассировки;
  • тестировать, корректировать, отлаживать набранные в отладчике или загруженные в отладчик фрагменты кода;
  • сохранять на диске (в виде исполняемых файлов com-типа) и загружать в отладчик фрагменты кода.

Студент должен освоить макрокоманды отладчика DEBUG, научиться набирать, тестировать, трассировать небольшие фрагменты кода (в пределах 10-20 ассемблерных команд).

ЦЕЛЬ : Знакомство с макрокомандами отладчика, процедурами набора, выполнения и трассировки фрагментов ассемблерного кода.

Лабораторная работа № 2

Тема : «Микропроцессор i8086: способы адресации на примере простейших команд ».

Краткая аннотация : данная работа посвящена знакомству с важнейшими способами адречации микропроцессора на примере простейших команд. К числу этих важнейших способов адресации относятся:

  • прямая адресация;
  • косвенная адресация.

Студент должен освоить важнейшие способы адресации процессора, научиться применять их для простейших команд процессора.

Приобретенный в ходе выполнения работы опыт должен позволить в последующем ориентироваться в листингах ассемблерных модулей

ЦЕЛЬ : Знакомство со способами адресации микропроцессора i8086 на примере простейших команд.

Введение .

Лабораторная работа № 3

Тема : «Ассемблер i8086: типовые примеры ».

Краткая аннотация : данная работа посвящена знакомству с типовыми примерами, выполненными с использованием команд ассемблера i8086. Перечень тем рассматриваемых ниже примеров таков:

  • копирование ячеек указанного диапазона;
  • занесение в ячейки указанного диапазона заданного ряда чисел;
  • поиск и замена образцов указанного диапазона;
  • подсчёт количества образцов указанного диапазона;
  • суммирование содержимого ячеек заданного диапазона;
  • нахождение минимального значения в заданном диапазоне;
  • нахождение максимального значения в заданном диапазоне.
  • ;
  • .

ЦЕЛЬ : Знакомство с простейшими типовыми примерами ассемблерных программ.

Студент должен освоить типовые примеры. Последнее означает:

  • умение выполнять ручную трассировку ассемблерного кода для диапазона из 3-4 ячеек ;
  • умение составлять ассемблерный код для 2-х диапазонов .

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

Типовые примеры ассемблерных программ.

В данной лабораторной работе собраны 7 простейших типовых программ-примеров:

  1. Копирование ячеек указанного диапазона.
  2. Занесение в ячейки указанного диапазона заданного ряда чисел.
  3. Поиск и замена образцов указанного диапазона.
  4. Подсчёт количества образцов указанного диапазона.
  5. Суммирование содержимого ячеек заданного диапазона.
  6. Нахождение минимального значения в заданном диапазоне.
  7. Нахождение максимального значения в заданном диапазоне.

К разряду простейших эти примеры отнесены по простой причине: ни в одном из них не требуется выводить символы на экран.
Во всех случаях действия осуществляются с числами, располагающимися в ячейках оперативной памяти.
Во всех случаях просмотр результатов предполагает использование отладчика DEBUG.
Все рассматриваемые программы-примеры собраны в рабочей папке, где хранятся файлы описания данной лабораторной работы.
Для загрузки этих файлов следует вспомнить раздел 1-ой лабораторной работы, в котором речь идёт о работе с файлами.

Команды, используемые в типовых примерах.

Типовой пример №1.

Копирование ячеек заданного диапазона:

УСЛОВИЕ ЗАДАНИЯ: Скопировать содержимое ячеек диапазона 130..13F в диапазон, начинающийся с адреса 150. (все данные в 16-ой системе) ПЛАН РЕШЕНИЯ : 1. Задание начальных значений (стартового адреса диапазона-источника= 130, стартового адреса диапазона-приёмника= 150, числа шагов цикла= 10). (все данные в 16-ой системе) Примечание . Расчет значения счетчика цикла: CX= (13F - 130) + 1 = F + 1 = 10 (расчёты в 16-ой системе) 2. Организация цикла: AL <- <- AL (последовательное копирование содержимого ячеек 130,131,132,...,13F в ячейки 150,151,152,...,15F соответственно) 3. Завершение работы программы (INT 20) КОД ПРОГРАММЫ : 100 MOV SI,0130 ; SI <- 130 (стартовый адрес диапазона-источника= 130) 103 MOV DI,0150 ; DI <- 150 (стартовый адрес диапазона-приёмника= 150) 106 MOV CX,0010 ; CX <- 10 (число шагов цикла = размеру дипазона = 10) ; цикл по перебору ячеек диапазона: 109 MOV AL, ; AL <- (копирование в регистр AL содержимого очередной ячейки диапазона) 10B MOV ,AL ; <- AL (размещение в очередной ячейке диапазона-приёмника содержимого AL) 10D INC SI ; SI <- SI + 1 (наращивание адреса диапазона-источника: +1) 10E INC DI ; DI <- DI + 1 (наращивание адреса диапазона-приёмника: +1) 10F LOOP 109 ; CX <- CX-1 После чего, если CX <> 0 - переход по адресу 109 111 INT 20 ; завершение работы ПРОВЕРКА РЕШЕНИЯ : Для проверки решения уменьшим значение счетчика цикла СХ до 3. Кроме того, будем считать, что изначально в ячейках 130..132 находятся следующие числа: = 10 = 11 = 12 100: SI = 130 103: DI = 150 106: CX = 3 (т.к. проверка проводится для первых 3-х ячеек диапазона) 109: AL = = 10 10B: = AL= 10 (содержимое 1-ой ячейки скопировано) 10D: SI= 130+1= 131 10E: DI= 150+1= 151 10F: CX= 3-1= 2 (CX=2>0, поэтому следует переход на адрес 109) 109: AL= = 11 10B: = AL = 11 (содержимое 2-ой ячейки скопировано) 10D: SI= 131+1= 132 10E: DI= 151+1= 152 10F: CX= 2-1= 1 (CX=1>0, поэтому следует переход на адрес 109) 109: AL= = 12 10B: = AL = 12 (содержимое 3-ей ячейки скопировано) 10D: SI= 132+1= 133 10E: DI= 152+1= 153 10F: CX= 1-1= 0 (CX= 0, поэтому цикл заканчивается) 111: INT 20 - завершение работы. РЕЗУЛЬТАТ РЕШЕНИЯ : = 10 = 11 = 12

Типовой пример №2.

Заполнение ячеек заданного диапазона указанным рядом чисел:

УСЛОВИЕ ЗАДАНИЯ: Ввести в ячейки с адреса 120 числа 7,B,...,FF (все данные в 16-ой системе) ПЛАН РЕШЕНИЯ : 1. Задание начальных значений (начального числа= 7, стартового адреса= 120, числа шагов цикла= 3F). Примечание . Расчет значения счетчика цикла: CX= (FF-7):4 + 1 = F8:4+1= 3E+1= 3F 2. Организация цикла: <- AL (последовательное заполнение ячеек 120,121,122,... числами 7,B,F,...,FF) 3. Завершение работы программы (INT 20) КОД ПРОГРАММЫ : 100 MOV AL,07 ; AL<- 7 (начальное число = 7) 102 MOV DI,0120 ; DI<- 120 (стартовый адрес = 120) 105 MOV CX,003F ; CX<- 3F (число шагов цикла= 3F) ; цикл по перебору ячеек диапазона: 108 MOV ,AL ; <- AL (размещение в очередной ячейке памяти очередного числа) 10A ADD AL,04 ; AL<- AL+4 (наращивание числа: +4) 10C ADD DI,0001 ; DI<- DI+1 (наращивание адреса: +1) 10F LOOP 108 ; CX<- CX-1 После чего, если CX<>0, следует переход по адресу 108 111 INT 20 ; завершение работы ПРОВЕРКА РЕШЕНИЯ : Для проверки решения уменьшим значение счетчика цикла СХ до 3. 100: AL= 7 102: DI= 120 105: CX= 3 (т.к. проверка проводится для первых 3-х ячеек диапазона) 108: = 7 10A: AL= 7+4= B 10C: DI= 120+1= 121 10F: CX= 3-1= 2 (CX=2>0, поэтому следует переход на адрес 108) 108: = B 10A: AL= B+4= F 10C: DI= 121+1= 122 10F: CX= 2-1= 1 (CX=1>0, поэтому следует переход на адрес 108) 108: = F 10A: AL= F+4= 13 10C: DI= 122+1= 123 10F: CX= 1-1= 0 (CX= 0, цикл завершен) 111: INT 20 - завершение работы. РЕЗУЛЬТАТ РЕШЕНИЯ : = 7 = B = F

Типовой пример №3.

Поиск и замена образца в заданном диапазоне:

УСЛОВИЕ ЗАДАНИЯ: Просмотреть ячейки 120..16F и заменить символ "9" символом "5". ПЛАН РЕШЕНИЯ : 1. Задание начальных значений до начала цикла (стартового адреса= 120, ASCII-кода символа "5"= 35, ASCII-кода символа "9"= 39, числа шагов цикла= 50). Примечание <->AH (последовательная проверка ячеек с целью поиска в них числа 39, заполнение очередной ячейки кодом 35, если найден символ "9", наращивание содержимого регистра DI) 3. Завершение работы программы (INT 20) КОД ПРОГРАММЫ : 100 MOV DI,0120 ; DI<- 120 103 MOV AL,35 ; AL<- 35 105 MOV AH,39 ; AH<- 39 107 MOV CX,0050 ; CX<- 50 ; цикл по перебору ячеек диапазона: 10A CMP ,AH ;<->AH 10C JNZ 0110 ; переход, если "Not Zero" (не равное 0 значение) 10E MOV ,AL ; <- AL (AL= 35) 110 INC DI ; DI<- DI+1 111 LOOP 010A ; CX<- CX-1, после чего, если CX<>0, переход на адрес 10А 113 INT 20 ; завершение работы ПРОВЕРКА РЕШЕНИЯ : Для проверки решения уменьшим значение счетчика цикла СХ до 3. В ячейках 120-122 разместим строку "193" 100: DI = 120 103: AL = 35 105: AH = 39 107: CX = 3 (т.к. проверка проводится для первых 3-х ячеек диапазона) 10A: = 31<->39 Не равно, т.е. имеет место "Not Zero" 10C: переход на адрес 110, т.к. имеет место "Not Zero" 110: DI= 120+1= 121 111: CX= 3-1= 2 (CX=2><->39 Равно, т.е. имеет место "Zero" 10C: переход на адрес 110 не следует, т.к. имеет место "Zero" 10E: = 35 110: DI= 121+1= 122 111: CX= 2-1= 1 (CX=1> <->39 Не равно, т.е. имеет место "Not Zero" 10C: переход на адрес 110, т.к. имеет место "Not Zero" 110: DI= 122+1= 123 111: CX= 1-1= 0 (CX=0, цикл завершен) 113: INT 20 - завершение работы. РЕЗУЛЬТАТ РЕШЕНИЯ : В ячейках 120-122 находятся символы "153"

Типовой пример №4.

Подсчёт количества образцов в заданном диапазоне:

УСЛОВИЕ ЗАДАНИЯ: Подсчитать количество символов «9» в диапазоне ячеек 120..16F. Результат сохранить в ячейке 170. ПЛАН РЕШЕНИЯ : 1. Задание начальных значений до начала цикла (стартового адреса= 120, ASCII-кода символа "5"= 35, счётчика образцов= 0, числа шагов цикла= 50). Примечание . Расчет значения счетчика цикла: CX= (16F-120)+ 1 = 4F+1= 50 2. Организация цикла: <->AH (последовательная проверка ячеек с целью поиска в них числа 39, наращивание значения счётчика образцов, если найден символ "9", наращивание содержимого регистра DI) 3. Завершение работы программы (INT 20) КОД ПРОГРАММЫ : 100 MOV DI,0120 ; DI<- 120 103 MOV AL,0 ; AL<- 0 105 MOV AH,39 ; AH<- 39 107 MOV CX,0050 ; CX<- 50 ; цикл по перебору ячеек диапазона: 10A CMP ,AH ;<->AH 10C JNZ 0110 ; переход, если "Not Zero" (не равное 0 значение) 10E INC AL ; AL<- AL+1 110 INC DI ; DI<- DI+1 111 LOOP 010A ; CX<- CX-1, после чего, если CX<>0, переход на адрес 10А 113 MOV ,AL; сохранение найденного количества образцов 116 INT 20 ; завершение работы ПРОВЕРКА РЕШЕНИЯ : Для проверки решения уменьшим значение счетчика цикла СХ до 3. В ячейках 120-122 разместим строку "193" 100: DI = 120 103: AL = 0 105: AH = 39 107: CX = 3 (т.к. проверка проводится для первых 3-х ячеек диапазона) 10A: = 31<->39 Не равно, т.е. имеет место "Not Zero" 10C: переход на адрес 110, т.к. имеет место "Not Zero" 110: DI= 120+1= 121 111: CX= 3-1= 2 (CX=2>0, поэтому следует переход на адрес 10А) 10A: = 39<->39 Равно, т.е. имеет место "Zero" 10C: переход на адрес 110 не следует, т.к. имеет место "Zero" 10E: AL= 0+1= 1 (один образец найден) 110: DI= 121+1= 122 111: CX= 2-1= 1 (CX=1> 0, поэтому следует переход на адрес 10А) 10A: = 33<->39 Не равно, т.е. имеет место "Not Zero" 10C: переход на адрес 110, т.к. имеет место "Not Zero" 110: DI= 122+1= 123 111: CX= 1-1= 0 (CX=0, цикл завершен) 113: = 1 (сохранение количества найденных образцов) 116: INT 20 - завершение работы. РЕЗУЛЬТАТ РЕШЕНИЯ : В ячейку 170 занесено число 1

Типовой пример №5.

Суммирование содержимого ячеек заданного диапазона:

УСЛОВИЕ ЗАДАНИЯ: Просуммировать содержимое ячеек 140..157. Результат сохранить в ячейках, начиная с ячейки 170 ПЛАН РЕШЕНИЯ : 1. Задание начальных значений (стартового адреса= 140, числа шагов цикла= 18, начального значения суммы= 0). 2. Организация цикла: (ADD AL,)и(ADC AH,00) (последовательное добавление содержимого ячеек 140..157 к накапливаемой сумме) 3. Сохранение найденной суммы (в ячейках памяти 0170 и 0171: =AL =AH). 4. Завершение работы программы (INT 20) КОД ПРОГРАММЫ : 100 MOV AX,0000 ; в регистре AX накапливаться сумма, поэтому AX = 0 103 MOV BP,0140 ; в регистр BP заносится стартовый адрес ячеек диапазона 106 MOV CX,0018 ; в регистр CX заносится количество ячеек диапазона; цикл по перебору ячеек диапазона: 109 ADD AL, ; добавление к содержимому AL содержимого ячейки 10C ADC AH,00 ; добавление 1, если регистр AL оказался переполненным 10F INC BP ; наращивание значения указателя адресов BP 110 LOOP 109 ; CX<- CX-1, после чего, если CX<>0, переход на адрес 10А 112 MOV ,AX ; сохранение в ячейках 170 и 171 найденной суммы 115 INT 20 ; завершение работы ПРОВЕРКА РЕШЕНИЯ : Для проверки решения уменьшим значение счетчика цикла СХ до 3. В ячейках 140-142 разместим числа 7A, D9, E6. 100: AX = 0 103: BP = 140 106: CX = 3 (т.к. проверка проводится для первых 3-х ячеек диапазона) 109: AL= AL+= 0+7A= 7A (кроме того, Carry Flag CF= 0) 10C: AH= AH+0+CF= 0+0+0= 0 10F: BP= 140+1= 141 110: CX= 3-1= 2 (CX=2>0, поэтому следует переход на адрес 109) 109: AL= AL+= 7A+D9= 53 (кроме того, Carry Flag CF= 1) 10C: AH= AH+0+CF= 0+0+1= 1 10F: BP= 141+1= 142 110: CX= 2-1= 1 (CX=1>0, поэтому следует переход на адрес 109) 109: AL= AL+= 53+E6= 39 (кроме того, Carry Flag CF= 1) 10C: AH= AH+0+CF= 1+0+1= 2 10F: BP= 142+1= 143 110: CX= 1-1= 0 (CX=0, цикл завершён) 112: = AL= 39 = AH= 2 (найденная сумма= 239) 116: INT 20 - завершение работы. РЕЗУЛЬТАТ РЕШЕНИЯ : В ячейку 170 занесено число 39, в ячейку 171 число 2.

Типовой пример №6.

Поиск минимального значения в заданном диапазоне:

УСЛОВИЕ ЗАДАНИЯ: Определить минимальное число диапазона 140..16F. Результат сохранить в ячейке 170. ПЛАН РЕШЕНИЯ : 1. Задание начальных значений (стартового адреса= 140, числа шагов цикла= 30, начального значения минимума= FF). 2. Организация цикла: (CMP DL,) (последовательное сопоставление содержимого ячеек 140..16F с текущим минимумом) 3. Сохранение найденного минимума (в ячейке памяти 0170: =DL). 4. Завершение работы программы (INT 20) КОД ПРОГРАММЫ : 100 MOV BP,0140 ; загрузка в регистр BP начального адреса 103 MOV CX,0030 ; в регистр CX заносится количество ячеек диапазона 106 MOV DL,FF ; в регистр DL заносится FF (начальное значение min) ; цикл по нахождению минимального значения: 108 CMP DL, ; текущий min DL сравнивается с содержимым очередной яч-ки 10B JBE 0110 ; если текущий min DL ≤ имеет место переход на 110 10D MOV DL, ; обновление текущего min DL (знач-е оказалось меньше) 110 INC BP ; наращивание адреса текущей ячейки памяти 111 LOOP 0108 ; цикл по перебору ячеек памяти 113 MOV ,DL ; сохранение в ячейке 170 найденного минимума 117 INT 20 ; завершение работы ПРОВЕРКА РЕШЕНИЯ : Для проверки решения уменьшим значение счетчика цикла СХ до 3. В ячейках 140-142 разместим строку "391" 100: BP = 140 103: CX = 3 (т.к. проверка проводится для первых 3-х ячеек диапазона) 106: DL = FF (начальное значение min) 108: DL<-> FF<->=33 Результат сравнения > (больше) 10B: переход на адрес 110 не следует, т.к. имеет место > (больше) 10D: DL= = 33 обновление текущего min DL 110: DI= 140+1= 141 111: CX= 3-1= 2 (CX=2><-> 33<->=39 Результат сравнения < (меньше) 10B: переход на адрес 110, т.к. условие переходы выполнено 110: DI= 141+1= 142 111: CX= 2-1= 1 (CX=1>0, поэтому следует переход на адрес 108) 108: DL<-> 33<->=31 Результат сравнения > (больше) 10B: переход на адрес 110 не следует, т.к. имеет место > (больше) 10D: DL= = 31 обновление текущего min DL 110: DI= 142+1= 143 111: CX= 1-1= 0 (CX=0, цикл завершён) 113: = DL= 31 (сохранение найденного min) 116: INT 20 - завершение работы. РЕЗУЛЬТАТ РЕШЕНИЯ : В ячейку 170 занесено значение минимума 31

Типовой пример №7.

Поиск максимального значения в заданном диапазоне:

УСЛОВИЕ ЗАДАНИЯ: Определить максимальное число диапазона 140..16F. Результат сохранить в ячейке 170. ПЛАН РЕШЕНИЯ : 1. Задание начальных значений (стартового адреса= 140, числа шагов цикла= 30, начального значения максимума= 0). 2. Организация цикла: (CMP DL,) (последовательное сопоставление содержимого ячеек 140..16F с текущим максимумом) 3. Сохранение найденного максимума (в ячейке памяти 0170: =DL). 4. Завершение работы программы (INT 20) КОД ПРОГРАММЫ : 100 MOV BP,0140 ; загрузка в регистр BP начального адреса 103 MOV CX,0030 ; в регистр CX заносится количество ячеек диапазона 106 MOV DL,0 ; в регистр DL заносится 0 (начальное значение max) ; цикл по нахождению максимального значения: 108 CMP DL, ; текущий max DL сравнивается с содержимым очередной яч-ки 10B JAE 0110 ; если текущий max DL ≥ имеет место переход на 110 10D MOV DL, ; обновление текущего max DL (знач-е оказалось больше) 110 INC BP ; наращивание адреса текущей ячейки памяти 111 LOOP 0108 ; цикл по перебору ячеек памяти 113 MOV ,DL ; сохранение в ячейке 170 найденного максимума 117 INT 20 ; завершение работы ПРОВЕРКА РЕШЕНИЯ : Для проверки решения уменьшим значение счетчика цикла СХ до 3. В ячейках 140-142 разместим строку "319" 100: BP = 140 103: CX = 3 (т.к. проверка проводится для первых 3-х ячеек диапазона) 106: DL = 0 (начальное значение max) 108: DL<-> 0<->=33 Результат сравнения < (меньше) 10B: переход на адрес 110 не следует, т.к. имеет место < (меньше) 10D: DL= = 33 обновление текущего max DL 110: DI= 140+1= 141 111: CX= 3-1= 2 (CX=2>0, поэтому следует переход на адрес 108) 108: DL<-> 33<->=31 Результат сравнения > (больше) 10B: переход на адрес 110, т.к. условие переходы выполнено 110: DI= 141+1= 142 111: CX= 2-1= 1 (CX=1>0, поэтому следует переход на адрес 108) 108: DL<-> 33<->=39 Результат сравнения < (меньше) 10B: переход на адрес 110 не следует, т.к. имеет место < (меньше) 10D: DL= = 39 обновление текущего max DL 110: DI= 142+1= 143 111: CX= 1-1= 0 (CX=0, цикл завершён) 113: = DL= 39 (сохранение найденного max) 116: INT 20 - завершение работы. РЕЗУЛЬТАТ РЕШЕНИЯ : В ячейку 170 занесено значение минимума 39

Задания к лабораторной работе:

Выполнить следующие задания :
  1. Изучить содержание лабораторной работы (в часы самоподготовки).
  2. Повторить выполнение разобранных в работе программ (в часы самоподготовки).
  3. Выполнить проверку решения типового задания "Подсчитать количество символов "7" в диапазоне ячеек 140..17E. Результат сохранить в ячейке 134". Проверку выполнить для первых 3-х ячеек диапазона (= 34;= 37;= 36).
  4. В диапазоне ячеек памяти 140-173 заменить все заглавные буквы "В", встречающиеся в этом диапазоне на строчные "в", а в диапазоне 174-183 определить максимальное значение, сохранив результат в ячейке 184.
  5. Выполнить проверку решения типового задания "Просуммировать содержимое ячеек 143..157. Результат сохранить в ячейках, начиная с ячейки 140". Проверку выполнить для первых 4-х ячеек диапазона (= AD;= BC;= FE;= ED).
  6. Скопировать содержимое ячеек диапазона 130-149 в диапазон, начинающийся адресом 150, а в диапазоне 16А-180 определить минимальное значение, сохранив результат в ячейке 181
  7. Выполнить проверку решения типового задания "Определить минимальное число диапазона 141..16F. Результат сохранить в ячейке 140". Проверку выполнить для первых 3-х ячеек диапазона (= 34;= 37;= 32).
  8. Занести в ячейки диапазона 140-149 числа 2, 6, A, …, а в диапазоне 15А-177 определить количество символов "6", сохранив результат в ячейке 181.
1. Абель П. Язык ассемблера для IBM PC и программирования. - М.: Высшая школа, 1992.- 447 с. 2. Лямин Л.В. Макроассемблер MASM. - М.: Радио и связь, 1994.- 320 с. 3. Нортон П., Соухэ Д. Язык ассемблера для IBM PC. – М.: "Компьютер", Финансы и статистика, 1992. –352 с. 4. Сван Т. Освоение Turbo Assembler. – Киев: "Диалектика", 1996. 5. Юров В. Assembler: учебный курс. – СПб: Питер, 1998. 6. Юров В., Хорошенко С. Assembler: учебный курс.-Санкт-Петербург: Питер, 1999. -672 7. Юров В. Assembler: Специальный справочник. – СПб: Питер, 2000. 8. Юров В. ASSEMBLER: практикум. (с дискетой).-Санкт-Петербург: Питер, 2002. -400 9. Юров В. Assembler: практикум – СПб: Питер, 2003.- 400 с. 10. Пирогов В.Ю. Ассемблер на примерах. - СПб.: БХВ-Петербург, 2005. - 416 с. 11. Пирогов В.Ю. Ассемблер для Windows. - 3-е изд. - СПб.: БХВ-Петербург, 2005. - 864 с. 12. Шнайдер О. Язык ассемблера для персонального компьютера фирмы IBM. Пер. с англ. под ред. Е.К.Масловского.-Москва: Мир, 1988. -405C. 13. Юров В.И. Assembler. Учебник для вузов. 2-ое изд. – СПб: Питер, 2005. - 637 с. 14. Использование Turbo Assembler при разработке программ. – Киев: "Диалектика", 1994. - 288 с.

Лабораторная работа № 4

Тема : «Функции ввода и вывода строк прерывания INT 21h ».

Краткая аннотация : данная работа посвящена знакомству с функциями ввода/вывода строк, что предполагает, в частности:

  • знакомство с 9-ой и 10-ой функциями прерывания INT 21h;
  • знакомство с форматом выводимой на экран строки;
  • знакомство со структурой буфера вводимой с клавиатуры строки;
  • знакомство с приёмами обработки введённой с клавиатуры строки.

Студент должен освоить приёмы использования функций ввода/вывода строк.

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

ЦЕЛЬ : Знакомство с функциями ввода/вывода строк и приёмами использования возможностей этих функций.

Вывод строк.

Краткое описание функции вывода строк прерывания INT 21h:

Программная реализация вывода строки в отладчике DEBUG:

Ввод строк.

Краткое описание функции ввода строки с клавиатуры (прерывание INT 21h):

Программная реализация ввода строки в отладчике DEBUG:

Ввод и вывод строк.

Задача . Запросить имя. Ввести это имя. Вывести именное приветствие.

Программа, представляющая собою решение задачи, имеет вид: -u 100 135 0CE7:0100 BA 40 01 MOV DX,0140 0CE7:0103 B4 09 MOV AH,09 0CE7:0105 CD 21 INT 21 OCE7:0107 BA 60 01 MOV DX,0160 0CE7:010A B4 0A MOV AH,0A 0CE7:010C CD 21 INT 21 0CE7:010E BA 5C 01 MOV DX,015C 0CE7:0111 B4 09 MOV AH,09 0CE7:0113 CD 21 INT 21 0CE7:0115 BD 40 01 MOV BP,0140 0CE7:0118 8A 4E 21 MOV CL, 0CE7:011B B5 00 MOV CH,00 0CE7:011D 8A 66 22 MOV AH, 0CE7:0120 88 66 47 MOV ,AH 0CE7:0123 45 INC BP 0CE7:0124 E2 F7 LOOP 01ID 0CE7:0126 B8 21 24 MOV AX,2421 0CE7:0129 89 46 47 MOV ,AX 0CE7:012C B4 09 MOV AH,09 0CE7:012E BA 80 01 MOV DX.0180 0CE7:0131 CD 21 INT 21 0CE7:0133 CD 20 INT 20 Состояние ячеек оперативной памяти перед запуском программы на исполнение: -d 140 I5O 0CE7:0140 57 68 61 74 27 73 20 79-6F 75 72 20 6E 61 6D 65 What"s your name 0CE7:0150 3F 20 20 24 00 00 00 00-00 00 00 00 0D 0A 24 00 ? $..........$. 0CE7:0160 1D 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0CE7:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0CE7:0180 48 65 6C 6C 6F 2C 20 00-00 00 00 00 00 00 00 00 Hello, ......... Результат запуска программы на исполнение: -G=100 What"s your name? Without Hello, Without! Программа завершилась нормально Состояние ячеек оперативной памяти по завершении работы программы: 0CE7:0140 57 68 61 74 27 73 20 79-6F 75 72 20 6E 61 6D 65 What"s your name 0CE7:0150 3F 20 20 24 00 00 00 00-00 00 00 00 0D 0A 24 00 ? $..........$. 0CE7:0160 1D 07 57 69 74 68 6F 75-74 0D 00 00 00 00 00 00 ..Without....... 0CE7:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 0CE7:0180 48 65 6C 6C 6F 2C 20 57-69 74 68 6F 75 74 21 24 Hello, Without!$

DEBUG . EXE – специальная системная программа для ввода и пошагового выполнения программ, написанных на машинном языке или с помощью команд ассемблера.

Для запуска этой программы нажмите кнопку Пуск , затем Выполнить , введите Debug и нажмите ввод , в результате программа должна загрузиться с диска в память.

После окончания загрузки на экране появится приглашение в виде дефиса, что свидетельствует о готовности программы Debug для приема команд.

Наиболее часто используемые инструкции Debug :

1. Q – выход из программы.

2. ? – получение справки.

3. H (Hexarithmetic) – шестнадцатеричная арифметика. Если после символа Н набрать 2 числа (размером не более 4 цифр каждое) через пробел, то получим сумму и разность набранных чисел:

4. R [<имя регистра>] – работа с регистрами (от слова Register). Инструкция «R» без параметра позволяет просмотреть содержимое всех регистров, а также значение флагов и команду, расположенную по смещению 0100 в сегменте кода. Обычно по смещению 0100 находится первая команда программы.

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

Как видим, при первом просмотре регистров командой r, в регистре АХ был 0, затем содержимое регистра было изменено.

5. U [<сегментный регистр>:]<начальный адрес>, <конечный адрес> – просмотр ячеек оперативной памяти, начиная с указанного смещения в сегменте, заданном сегментным регистром. Команда U (Unassemble) дизассемблирует команды, находящиеся в памяти по заданному адресу.

Например, в следующем примере мы просматриваем команды, находящиеся в регистре CS, начиная с адреса 100, по адрес 102.

6. Е [<сегментный регистр>:]<смещение> – запись информации в ячейки оперативной памяти.

Как было сказано, с помощью Debug можно вводить команды как на машинном языке, так и на языке ассемблера. Инструкция Debug E (Enter) служит для ввода команд на машинном языке . Здесь Debug используется как интерпретатор, чтобы работать непосредственно с микропроцессором. Можно задавать машинные команды, записывать их в определенное место оперативной памяти, обычно, начиная с 0100 смещения относительно начала сегмента кода. Затем выполнять пошагово (по одной команде) либо сразу всю программу.

Так как микропроцессор понимает только двоичные числа (сокращенно их можно записать шестнадцатеричными), то и коды машинных команд записываются в виде шестнадцатеричных чисел, причем команды бывают одно-, двух- трехбайтовые и т.д.

Например, команда для сложения значений из регистров АХ и ВХ двухбайтовая и имеет машинный код 01D8.

Инструкция “E <смещение>” при работе распечатывает в следующей после ее ввода строке адрес, состоящий из двух чисел, и старое значение байта по этому адресу: <содержимое CS>:<смещение><значение байта>, далее компьютер ожидает ввода нового значения байта.

Для ввода, например, двухбайтовой машинной команды 01D8 нужно записать 01 в сегмент кода по смещению 100, и D8 – по смещению 101:

7. Т (от Tracing)– запуск программы, находящейся в оперативной памяти по адресу 0100, в пошаговом режиме. Для вызова программы на выполнение нужно предварительно позаботиться, чтобы в регистре IP (счетчик команд) было число 0100.

8. А <смещение> – ввод команд в ассемблерном виде (от Assemble). Первую команду программы следует начинать вводить со смещения 0100. Далее система ждет поочередного ввода команд ассемблера. Для окончания ввода нужно нажать Enter после пустой строки.

Пример . Введем в оперативную память программу на ассемблере, выполняющую сложение двух чисел. Установим начальный адрес следующим образом: A 0100 .

Отладчик выдаст значение адреса сегмента кодов и смещения в виде хххх:0100. Теперь можно вводить каждую команду, завершая клавишей Ввод.

Прежде чем выполнить программу, проверим сгенерированные машинные коды при помощи команды U. Необходимо сообщить отладчику адреса первой и последней команд, которые необходимо просмотреть, в данном случае 0100 и 0106. Введите: U 100, 106

Как видим, машинные коды сгенерированы верно.

С помощью команды R выведем содержимое регистров и первую команду нашей программы:

С помощью команд Т выполним последовательно все команды программы:

Так вводятся и трассируются программы на языке ассемблера.

Изучим остальные команды Debug, после чего вернемся к примеру.

9. G (от Go) – запуск программы, находящейся в оперативной памяти по адресу 0100. Для вызова программы на выполнение нужно предварительно позаботиться, чтобы в регистре IP (счетчик команд) было число 0100.

10. N <имя.com-файла> – задает имя программы (Name) для последующей записи ее на диск либо считывания с диска. Перед записью предварительно нужно записать 0 в регистр ВХ, а размер программы (в байтах) – в регистр СХ.

11. W (от Write) – запись программы на диск. После выполнения инструкции “W” на диске в текущей директории появится файл с расширением.COM – точная копия веденной программы.

программы с диска в оперативную память. Предварительно имя программы задается с помощью команды N.

Вернемся к примеру со сложением двух чисел. Чтобы записать эту программу на диск, следует выполнить три действия:

1. присвоить программе имя;

2. указать длину программы;

3. выполнить запись.

1. Присвоим будущему файлу имя с помощью команды N.

2. Программа состоит из четырех двухбайтных инструкций, занимает адреса со смещениями с 0100 по 0106, значит ее длина – 8 байт. Размер программы Debug хранит в регистровой паре . В нашем случае значение длины умещается в одном регистре, поэтому старший регистр пары мы просто обнулим: BX=0, CX=8.

3. Для записи программы на диск используем программу W.

Отладчик DEBUG предназначен для решения широкого круга задач. К ним относятся, например, следующие задачи: изучение текущего содержимого оперативной памяти; дизассемблирование.COM и.EXE-файлов;разработка и отладка собственных программ на языке ассемблера; изучение работы программ и их модификация; тестирование периферийного оборудования, для работы с портами ввода/вывода напрямую (в диалоговом режиме); изучение системы команд процессора, прерываний BIOS и MS-DOS.

Существует два способа запуска отладчика:

debug (Enter) или debug filename (Enter)

После запуска отладчик загружается в оперативную память, а содержимое сегментных регистров CS, DS, ES, SS - на первый свободный параграф сразу после самого отладчика. Регистр IP устанавливается равным 100.

Отладчик DEBUG имеет специальный указатель адреса данных, который используется по умолчанию во многих командах отладчика.

После запуска отладчика слева на экране появляется черта [-], которая указывает на то, что отладчик ждет команду. Все числа интерпретируются отладчиком в шестнадцатеричной системе исчисления.

КОМАНДЫ ОТЛАДЧИКА DEBUG

А - команда ассемблирования. Эта команда позволяет вводить программы с использованием мнемокода команд в оперативную память. Ввод команды отладчика

А <число> (Enter)

заставляет его перейти в режим приема команд с клавиатуры и последовательного размещения их, начиная с адреса, равному указанному в команде. При вводе можно использовать две популярные инструкции ассемблера DB и DW. Например:

DB 1,2,3,”EXAMPLE”

DW 1000,2000,”FFFF”

Отладчик поддерживает мнемоники всех команд процессора, а также и сопроцессора 80Х87. При ассемблировании команд JMP и CALL по умолчанию, если это возможно, используется SHORT - вариант этих команд. Но можно указывать перед адресом перехода NEAR или FAR, что приведет к генерации соответствующих команд. Мнемоникой оператора RET, соответствующего дальнему вызову CALL FAR является RETF. Возможно, а в сомнительных случаях необходимо, использовать указатели WORD PTR или BYTE PTR. При вводе программы допускается печать префиксов CS:, ES:, SS: впереди команды в той же строке.

Пример. Программа заполнения экрана символом “!”.

Наберите А 200 (Enter), затем введите программу

В конце программы стоит команда INT 20, обеспечивающая возврат управления обратно на монитор команд отладчика. Запустите эту программу по команде

С - сравнение. Зта команда сравнивает побайтно две области памяти и печатает все различия между ними в форме

<адрес> <содержимое> <содержимое> <адрес>

В данной записи слева приведена информация о первой области памяти, а справа - о второй.

Пример. Сравнить два блока памяти длинной 256 байт. Первый начинается с адреса 100, второй с адреса 300.

Для этого надо набрать

С 100L100 300 (Enter)

Эта команда может быть полезна, например, при проверке на идентичность двух дискет. Для этого в соседние области памяти загружаются интересующие нас соответствующие блоки этих дискет, которые затем анализируются командой С.

D - дамп оперативнойй памяти. Эта команда дает на дисплее распечатку указанной области оперативной памяти, представленной в шестнадцатеричной системе счисления, а справа дает их символьное представление. Причем, кодовые комбинации, не имеющие символьного представления в стандарте ASCII, изображаются точками. В строке отображается шестнадцать байт. При этом справа указывается полный адрес самого левого бaйта. Таким образом, в одной строке приводится шестнадцатеричный дамп, а также ASCII-дамп шестнадцати байт оперативной памяти. Если команда D дана без параметров, то всего на экране отображается 128 байт (80Н) в восьми строках. В каждой строке имеется знак “-“, разделяющий 16 байт пополам: между восьмым и девятым байтами.

Пример. Просмотреть указатели-вектора первых тридцати двух прерываний (20Н).

Необходимо ввести команду

D 0:0,7F (Enter)

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

Ввод команды:

Е <адрес> (Еnter)

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

а) “пробел”, что означает переход к редактированию следующего байта;

б) “Enter”. Это приведет к выходу из режима побайтного редактирования на командный уровень отладчика;

в) “-“. Нажатие этого знака приведет к переходу на редактирование предыдущего байта.

Пример. Изменить значение счетчика системных часов.

Введем команду

и наберем четыре числа 70 70 70 70, разделенных пробелами, затеv символ возврата каретки 0D. Далее необходимо выйти из отладчика и выполнить команду time операционной системы.

F - команда заполнения. Эта команда позволяет заполнить содержимоt указанного диапазона оперативной памяти повторяющейся цепочкой байтов заданным и значениями. В частности, когда цепочка состоит из одного байта, эта команда позволяет обнулить нужную область памяти, когда байт равен нулю, а также занести во все биты единицу, заполняя байтом равным FF.

Команда имеет следующий синтаксис:

F <диапазон_памяти> <цепочка байтов> (Enter)

Пример. Заполнить область памяти, начинающуюся с адреса DS:0100 нулями общим числом 16384 байта (4000 16).

F 100L4000 00 (Enter)

Проверить командой

D 100L4000 (Enter)

G - команда запуска программы programmy. Эта команда предназначена для запуска программы на исполнение. При этом, если той области памяти, где хранятся данные, передается управление как программе, компьютер “зависает”, и требуется его повторный запуск. В случае, когда в программе имеются серьезные ошибки (например, отсутствует оператор INT 20 возврата на командный уровень отладчика), попытка исполнить ее с помощью оператора G также приводит к зависанию компьютера.

Этот оператор обычно используется в одной из следующих четырех форм:

Исполнение этого оператора сводится к передаче управления адресу CS:IP. Значения CS и IP можно узнать набрав команду R (Enter)дампа всех регистров процессора;

б) G=<адрес> (Enter)

При этом производится запуск программы по указанному адресу.

в) G <адрес> (Enter)

В этом случае программа запускается с адреса CS:IP и при достижении оператора с указанным адресом осуществляется BREAK- остановка исполнения программы. Распространенной ошибкой начинающих является пропуск знака “равно” при использовании команды G. В этом случае указанный адрес воспринимается как адрес останова, и если CS:IP указывал, например на область данных, то компьютер “зависнет”.

г) G=<адрес> <другой_адрес> (Еnter)

в этом случае производится запуск программы с указанного после знака “=” адреса и в случае достижения программой команды с величиной адреса, указанного вторым (другой адрес), происходит остановка. Такой способ остановки программы называется введением контрольной точки останова. При указании контрольной точки останова соответствующий байт команды по этому адресу заменяется командой INT 3, имеющей размер 1 байт. При достижении контрольной точки исходное значение байта восстанавливается.

Сначала введем программу (с помощью команды А 100):

MOV ,1234

DEC BX ;здесь поставить контрольную точку

Запустим программу командой G=100 109 (Еnter) Программа, дойдя до адреса 109, остановилась и дала полный дамп регистров.

Н - команда шестнадцатиричной арифметики. Эта команда позволяет получить сумму и разность двух указанных в команде шестнадцатеричных чисел.

В ответ получим 1 (сумма) и FFFF (разность).

I - команда ввода из порта. Эта команда позволяет прочесть содержимое порта ввода/вывода с указанным адресом, распечатав его на экране в шестнадцатиричном виде.

Синтаксис команды:

I <адрес_порта> (Enter)

При этом мы получим содержимое порта В из программируемого периферийного интерфейса 82 .

L - команда загрузки с диска. Эта команда позволяет загружать как логические сектора с флоппи-дисков и винчестеров, так и отдельные файлы. Загрузка секторов с диска производится командой:

L<адрес><номер_диска><начальный_сектор><число_секторов> (Enter)

Здесь “адрес” означает начальный адрес в оперативной памяти, начиная с которого будет последовательно размещаться содержимое блоков-секторов. Переменная “номер диска” указывает с какого диска будет производиться загрузка. Число 0 означает диск А, число 1 - диск В, число 2 - диск С и т.д. Следующие две переменные соответственно указывают с какого сектора начинается чтение и общее число прочитанных секторов.

Загрузить BOOT-блок с флоппи-диска А: в оперативную память, начиная с адреса DS:1000, для чего необходимо выполнить команду

L 1000 0 0 1 (Enter)

Затем содержимое ВООТ-блока можно распечатать командой

D 1000L200 (Enter)

а также дизассемблировать

U 1000L200 (Enter)

N <имя_файла> (Enter)

Далее необходимо исполнить команду L без аргументов. В результате этих действий файл (за исключением файлов с расширением ЕХЕ), будет загружен в оперативную память начиная с адреса CS:100. Если загружаемый файл имеет расширение ЕХЕ, то отладчик загрузит файл, начиная с адреса СS:0. Число прочитанных байтов хранится в регистровой паре ВХ:СХ после выполнения команды L.

M - команда копирования.Эта команда копирует содержимого части оперативной памяти в другую область оперативной памяти. Синтаксис команды следующий:

М <диапазон> <начальный_адрес> (Enter)

Здесь “диапазон” указывает на копируемую область памяти, а “начальный_адрес” - на адрес первого байта, начиная с которого размещаются скопированные данные. Эту команду можно использовать для временного сохранения содержимого оперативной памяти с ее последующим восстановлением.

В начале просмотрим содержимое памяти:

D 100L100 (Enter)

Затем сохраним часть памяти, начиная с адреса

M 100L100 1000 (Enter)

Затрем исходное содержимое

F 100L100 0 (Enter)

Проверим обнуление

D 100L100 (Enter)

И наконец восстановим исходное содержимое

M 100L100 100 (Enter)

N - команда указания имени. Эта команда прежде всего, определяет имя файла, который далее либо будет считываться с диска командой L, либо записываться на диск командой W. Синтаксис этой команды следующий:

N <имя_файла> (Enter)

Прочитаем с диска в оперативную память файл AUTOEXEC.BAT. Для этого выполним

N C:\AUTOEXEC.BAT (Enter)

В регистровую пару ВХ:СХ, будет занесена длина загруженного файла в байтах.

О - команда вывода данных в порт. Эта команда позволяет вывести указанный байт в порт с заданным адресом. Она полезна для тестирования работы периферийных устройств и корпусов на системной плате в диалоговом режиме. Синтаксис команды:

О <адрес_порта> <величина> (Enter)

Здесь вместо «адреса_порта» подставляется адрес необходимого порта в диапазоне 0-FFFF, а вместо “величина” - значение, которое затем загружается в порт. Если порт шестнадцатибитный, то “величина” может быть четырехразрядным шестнадцатиричным числом, которое загружается в порт.

Мотор дисковода А: для флоппи-диска можно включить следующей командой

О 3F2 10 (Enter)

Р - команда высокоуровневой трассировки. Эта команда также, как и команда Т, предназначена для трассировки программ. Однако, в отличие от Т трассировки, эта трассировка менее детальна. Она не отслеживает досконально подпрограммы и программные прерывания, а также циклы LООР и строковые команды с повторением. Как и в случае Т-трассировки после каждой команды печатается содержимое всех регистров и следующая исполняемая команда. Синтаксис команды:

Р=<адрес> <число_команд> (Enter)

Можно опустить любой из двух параметров командной строки: <адрес> и/или <число_команд>. Параметр<адрес> задает начальный адрес, начиная с которого будет производиться трассировка, а параметр <число_команд> будет указывать общее число команд, которые будут исполнены после нажатия клавиши (Enter). Обязателен ввод символа “=” при указании адреса для того, чтобы не спутать адрес с числом исполняемых команд. Этот тип Р -трассировки крайне полезен при изучении общей логики выполнения программы, избавляя от утомительного отслеживания деталей. При начальном изучении программы необходимо начинать именно с Р -трассировки.

Введем, начиная с адреса 100, следующую программу

Затем проведем Р-трассировку. Для этого сначала введем команду Р=100 (Enter) и далее последовательные

После этого проведем обычную детальную Т-трассировку

Q - команда выхода из отладчика. Команда Q приводит к выходу из отладчика на следующий верхний программный уровень. При этом рабочие файлы не сохраняются.

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

дает распечатку всех регистров, а также команды, на которую указывает CS:IP.

R <имя_регистра> (Enter)

дает распечатку содержимого указанного регистра, и затем печатает двоеточие на следующей строке. После этого пользователь может нажать клавишу (Enter) и выйти обратно на монитор команд отладчика, либо задать новое значение регистра перед нажатием клавиши (Enter). В последнем случае старое значение регистра заменится на новое. Возможные имена регистров: AX, BX, CX, DX, SP, BP, SI, DI, DS, ES, SS, CS, IP, F (регистр флагов).

При использовании команды

надо учитывать, что кодирование значений флагов производится весьма специфическим образом. Ниже приводится таблица кодировки, где символьная пара слева соответствует значению 0 соответствующего флага, а справа - значению, равному 1 (флаг установлен):

При исполнении команды

значения флагов печатаются в строку в порядке, обратном к порядку в таблице. Сразу же за этим в строке печатается знак черты <->, отладчик переходит в состояние ожидания ввода с клавиатуры. Если пользователь нажмет только клавишу (Enter), то значения флагов не изменятся и произойдет возврат на монитор команд отладчика. Однако, перед этим пользователь может набрать новые значения некоторых флагов согласно кодировочной таблицы. Порядок следования при этом не существенен.

S - команда поиска. Команда поиска упорядоченного набора байтов позволяет провести поиск указанной цепочки байт в заданном диапазоне оперативной памяти и имеет синтаксис:

S <диапазон_памяти> <цепочка_байтов> (Enter)

Ответ выдается в виде списка адресов, начиная с которых располагается указанная цепочка байтов.

Предположим, нужно определить встречается ли цепочка символов “DOS” в первых 32К оперативной памяти. Для этого необходимо ввести команду

S 0:0L8000 44 4F 53 (Enter)

Т - команда трассировки. Эта команда позволяет исполнить одну или несколько команд в режиме трассировки с печатью содержимого всех регистров и мнемоники следующей декодированной исполняемой команды. После трассировки текущей команды указатель IР сдвигается так, что он указывает на следующую команду. Команда

производит трассировку одной текущей команды, на которую указывает CS:IP, с соответствующим изменением IP.

T <число> (Enter)

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

Т=<адрес> (Enter)

трассирует одну команду по указанному адресу.

Общий вид команды Т следующий:

Т=<адрес> <число_команд> (Enter)

Команда: Т=FFFF:0 (Enter)

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

U - команда дизассемблирования. Эта команда позволяет дизассемблировать программы, загруженные в рабочую область отладчика.Общий синтаксис:

U <начальный_адрес> <длина> (Enter)

U <начальный_адрес>,<конечный_адрес> (Enter)

вызывает дизассемблирование 32 байт, начиная с байта, на который указывает CS:IP с выводом результирующего листинга на дисплей.

W - команда записи на диск. Эта команда позволяет записывать на диск (флоппи-диски или винчестер) в последовательные блоки указанный диапазон оперативной памяти, а также записывать в файлы. Запись в секторы на диск производится командой

W<адрес><номер_диска><начальный_сектор><число_секторов> (Enter)

Эта команда записывает на диск не более 80Н секторов, число секторов не более 80. Параметр <адрес> означает адрес оперативной памяти, начиная с которого содержимое памяти копируется на диск. Параметр <номер диска> указывает диск, на который производится запись (0-диск А:, 1-диск В:, ..., 80 - винчестер С:). Параметр <начальный сектор> указывает номер логического сектора, начиная с которого будет производиться загрузка образа оперативной памяти. Параметр <число секторов> указывает общее количество записываемых на диске секторов.

Скопируем в файл на диске содержимое ВIОS-области оперативной памяти. Предполагая наличие РС/АТ со стандартным ВIОS размером 64К, обнулим сначала регистр ВХ, а затем занесем в регистр СХ 2000Н. Далее зададим имя файла, куда будем копировать старшую половину ВIОS, командой

N ВIОS.СОМ (Enter)

И наконец, команда

W F000:Е000 (Enter)

занесет в файл ВIОS.СОМ содержимое BIOS.