Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Dos7book

.pdf
Скачиваний:
75
Добавлен:
09.02.2015
Размер:
5.1 Mб
Скачать

Глава 6: Избранные программы для MS-DOS7

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

6.05-12 Отладчик DEBUG.EXE: команда "Name"

Команда "Name" (= имя) объявляет имя файла, который затем должен быть загружен командой "Load" (6.05-10) или записан командой "Write" (6.05-19). В командной строке отладчика DEBUG.EXE вызов команды "Name" задается буквой

"N":

N Trial.com /S /D

После буквы "N" должно быть указано объявляемое имя файла. Если у имени имеется суффикс, то он должен быть указан обязательно. Имени может предшествовать путь, после имени может следовать группа передаваемых файлу параметров (как "/S /D" в данном примере).

Все данные, объявляемые командой "Name", записываются в область PSP (A.07-1), созданную отладчиком для отлаживаемой программы, начиная с адреса DS:0081. Кроме того, длина строки данных записывается в ячейку DS:0080, имя файла без суффикса записывается начиная с адреса DS:005D, а суффикс начиная с адреса DS:0065. Поскольку все эти адреса отсчитываются относительно сегментного регистра DS:, постольку записанные данные станут недоступны командам "Load" и "Write", как только сегментный адрес в регистре DS: изменится. Когда команда "Name" исполняется без параметров, она затирает данные в ячейках

DS:005C – DS:0080 и записывает код 0Dh в ячейку DS:0081.

Примечание 1: по умолчанию начальные значения сегментных адресов в регистрах CS: и DS: устанавливаются одинаковыми. Поэтому при размещении

исполняемого кода отлаживаемой программы в области ниже принимаемого по умолчанию адреса CS:0100h, он может оказаться записанным поверх данных PSP (A.07-1) и, помимо того, сам может быть перезаписан данными, вводимыми командой "Name".

6.05-13 Отладчик DEBUG.EXE: команда "Output"

Команда "Output" (= выдать) посылает байт данных в указанный порт. В командной строке отладчика DEBUG.EXE вызов команды "Output" задается буквой

"O":

O 0378 00

После буквы "O" в командной строке должны быть указаны два обязательных параметра. Первый параметр представляет четырехзначный шестнадцатеричный адрес порта, куда следует послать байт данных (00h), определяемый вторым

– 181 –

Глава 6: Избранные программы для MS-DOS7

параметром. Приведенный в показанном примере адрес 0378h обычно принадлежит порту LPT1. Сегментный адрес перед адресом порта не имеет смысла и не допускается. Нули в старших разрядах адреса порта можно не указывать. Адреса некоторых портов приведены в приложении A.14-1.

Примечание 1: неосторожное пользование командой "Output" может привести к нарушению режимов работы аппаратных средств компьютера.

6.05-14 Отладчик DEBUG.EXE: команда "Proceed"

Команда "Proceed" (= продвигаться) выполняет заданное число машинных команд, причем выполняет циклы (LOOP, LOOPZ, LOOPNZ), вызовы (CALL), повторения (REPZ, REPNZ) и прерывания как одну машинную команду. В этом главное отличие команды "Proceed" от команды "Trace" (6.05-17).

В командной строке отладчика DEBUG.EXE вызов команды "Proceed" задается буквой "P":

P =0100 5

В приведенном примере после буквы "P" следуют два параметра. Первый параметр это адрес, с которого нужно начать исполнение команд, перед этим адресом должен стоять знак равенства. Адрес можно указывать в любой допустимой форме (6.05-01). Если вместо адреса указано только смещение, то сегментный адрес по умолчанию будет взят из регистра CS:. Второй параметр количество подлежащих исполнению команд. Если количество не указано, по умолчанию будет исполнена одна команда. Если вообще ни один параметр не указан, то будет исполнена одна машинная команда по адресу CS:IP.

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

Примечание 1: команду "Proceed" нельзя применять для исполнения машинных кодов, считываемых из постоянной памяти (ROM), для этого годится только команда "Trace" (6.05-17).

6.05-15 Отладчик DEBUG.EXE: команда "Register"

Команда "Register" (= регистр), заданная в командной строке одной буквой "R" без параметров, выводит на экран состояния регистров и флагов процессора. Типичные состояния регистров и флагов, устанавливаемые в момент запуска отладчика DEBUG.EXE на исполнение, показаны на рис. 1.

– 182 –

Глава 6: Избранные программы для MS-DOS7

Рис. 1

Обратите внимание, что в сегментные регистры (DS, ES, SS, CS) записано одно и то же число: это сегментный адрес участка памяти, выделенного операционной системой для отлаживаемой программы. Другие регистры и флаги в начальный момент приобретают фиксированные исходные состояния. Двухбуквенные обозначения начальных состояний флагов расшифровывают следующим образом:

NV

No oVerflow = нет переполнения,

UP

count UP = счет индексов на увеличение,

EI

Enable Interrupts = прерывания разрешены,

PL

Positive sign = положительное число,

NZ

No Zero = ненулевое значение или неравенство,

NA

No Auxiliary carry = нет переноса в 4-м разряде,

PO

Parity Odd = нечетная сумма битов младшего байта,

NC

No Carry = нет переноса в старшем разряде.

В последней строке выводимого на экран сообщения показаны код и дизассемблированное представление машинной команды, которая находится по адресу CS:IP. Именно эта машинная команда будет исполнена, если отладчик получит команду "Trace" или "Proceed" с параметрами по умолчанию.

Чтобы получить возможность изменять состояние флагов процессора, в командной строке после буквы "R" должен быть указан параметр "F":

RF

Вответ отладчик DEBUG.EXE показывает двухбуквенные обозначения

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

OV

OVerflow = переполнение,

DN

count DowN = счет индексов на уменьшение,

DI

Disable Interrupts = прерывания запрещены,

NG

NeGative sign = отрицательное число,

ZR

ZeRo = нулевое значение или равенство,

AC

Auxiliary Carry = перенос в 4-м разряде,

PE

Parity Even = четная сумма битов младшего байта,

CY

CarrY = перенос в старшем разряде.

– 183 –

Глава 6: Избранные программы для MS-DOS7

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

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

R AX

Приведенный здесь пример команды откроет регистр AX процессора для записи в него нового значения. Для записи командой "Register" также доступны регистры

BX, CX, DX, BP, SP, DI, SI, CS, DS, ES, SS ,IP (и PC – это еще одно имя регистра

IP). При исполнении каждой такой команды отладчик DEBUG.EXE показывает записанное в регистр значение и двоеточие, приглашая тем самым ввести новое четырехзначное шестнадцатеричное значение в этот регистр. Если Вы не введете ничего и просто нажмете клавишу ENTER, то прежнее значение в данном регистре сохранится. Команда "R" не предоставляет раздельного доступа к младшему и старшему байтам (например, AH и AL) 16-разрядных регистров. Если нужно изменить состояние только одного из них, то в другой байт нужно повторно записать прежнее значение.

Примечание 1: упоминаемые здесь 8 флагов это лишь часть флагов центрального процессора, перечень которых приведен в разделе A.11-4.

6.05-16 Отладчик DEBUG.EXE: команда "Search"

Команда "Search" (= поиск) выполняет поиск представленной последовательности данных в указанной области адресного пространства. В командной строке отладчика DEBUG.EXE вызов команды "Search" задается буквой

"S":

S 0100 L200 20 'st'

В приведенном примере первый параметр это адрес первой ячейки из той области, в пределах которой надо проводить поиск. Здесь допустимы все формы адресов, перечисленные в разделе 6.05-01. Если сегмент в адресе не указан, то по умолчанию он будет взят из регистра DS:. Второй параметр задает либо смещение для конечной ячейки области поиска (если числу не предшествует буква "L"), либо длину области поиска; в данном случае заявлена длина 200h байт. Третий и все

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

Данные искомой последовательности в командной строке могут быть представлены либо побайтно, по две шестнадцатеричных цифры на байт, либо

– 184 –

Глава 6: Избранные программы для MS-DOS7

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

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

После нажатия клавиши ENTER отладчик DEBUG.EXE покажет все адреса в пределах области поиска, где искомая последовательность будет найдена. Следует иметь ввиду, что DEBUG.EXE не анализирует, какую миссию выполняют найденные фрагменты. Одни и те же последовательности байтов могут представлять собой данные, а могут входить в состав исполняемых команд. Все неопределенности такого рода предоставляется разрешать пользователю.

6.05-17 Отладчик DEBUG.EXE: команда "Trace"

Команда "Trace" (= проследить) выполняет заданное число машинных команд, начиная с указанного адреса. В отличие от команды "Proceed" (6.05-14), команда "Trace" прослеживает исполнение машинных кодов в составе циклов, вызовов подпрограмм и т.п. В командной строке отладчика DEBUG.EXE вызов команды "Trace" задается буквой "T":

T =0100 5

В приведенном примере после буквы "T" следуют два параметра. Первый параметр это адрес, с которого нужно начать исполнение команд, перед этим адресом должен стоять знак равенства. Адрес можно указывать в любой допустимой форме (6.05-01). Если вместо адреса указано только смещение, то сегментный адрес по умолчанию будет взят из регистра CS:. Второй параметр количество подлежащих исполнению команд. Если количество не указано, по умолчанию будет исполнена одна команда. Если вообще ни один параметр не указан, то будет исполнена одна машинная команда по адресу CS:IP.

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

Примечание1: команду "Trace" не следует применять для исполнения прерываний, вызовов подпрограмм и других машинных команд, которые

вовлекают в процесс исполнения фрагменты уже отлаженного машинного кода. Для этого лучше использовать команду "Proceed" (6.05-14).

– 185 –

Глава 6: Избранные программы для MS-DOS7

6.05-18 Отладчик DEBUG.EXE: команда "Unassemble"

Команда "Unassemble" (= дизассемблировать) переводит машинные коды команд в форму ассемблерных команд и показывает их на экране. В командной строке отладчика DEBUG.EXE вызов команды "Unassemble" задается буквой "U":

U 014B L10

Первый параметр команды "Unassemble" – стартовый адрес того фрагмента машинного кода, который надлежит перевести. Адрес можно указывать в любой допустимой форме (6.05-01). Если указано только смещение, то сегментный адрес по умолчанию будет взят из регистра CS:. Второй параметр означает либо конечное смещение того же фрагмента (если ему не предшествует буква "L"), либо его длину, в данном примере длину 10h (= 16) байт. Когда параметры при команде "Unassemble" вообще не указаны, тогда переводятся 20h байт, начиная с текущего смещения относительно регистра CS:. При каждом исполнении текущее смещение увеличивается на длину дизассемблированного фрагмента, так что каждое следующее исполнение команды "Unassemble" без параметров показывает результат дизассемблирования следующего фрагмента машинного кода.

Важно иметь ввиду, что команда "Unassemble" не отличает исполняемый машинный код от других данных, и не способна находить первый байт в многобайтовых машинных командах. Если дизассемблированию подвергаются данные, или если заданный пользователем стартовый адрес не соответствует первому байту машинной команды, то в результате дизассемблирования получается ерунда. Два примера дизассемблирования при правильном и при неправильном указании стартового адреса показаны на рис. 2.

Рис. 2

– 186 –

Глава 6: Избранные программы для MS-DOS7

Обратите внимание, что при неправильном указании стартового адреса (0180h) две первых машинных команды (0180h и 0184h) дизассемблируются неверно, но начиная со смещения 0188h "фаза" дизассемблирования все-таки устанавливается правильно. Стохастический процесс установления занимает до 10h байт; далее его влияние на дизассемблирование команд обычно не распространяется.

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

путаницы любой исполняемый код при дизассемблировании всегда должен быть размещен в памяти точно так же, как его следует размещать для исполнения, то есть начиная с адреса CS:0000h для драйверов и с адреса CS:0100h для исполняемого кода программ с суффиксами *.COM и *.EXE.

Интерпретация команд при дизассемблировании, конечно, должна быть идентична их интерпретации процессором. Но процессор может интерпретировать одни и те же машинные коды по-разному в зависимости от состояния бита разрядности в дескрипторе сегмента кода (примечание 5 к A.12-2). Кроме того, некоторые коды интерпретируются особым образом только 64-разрядными процессорами. Должное состояние того процессора, для которого предназначен анализируемый машинный код, отладчик DEBUG.EXE выяснять "не умеет". Он дизассемблирует только коды, предназначенные для 16-разрядного исполнения. Иные машинные коды предоставлять отладчику бессмысленно.

При дизассемблировании иногда встречаются коды команд, которые отладчик DEBUG.EXE "не знает". В таких случаях лучше обратиться к более "толковому" варианту DEBUG.EXE, упоминаемому в примечании 2 при вводной статье к разделу 6.05. Еще более респектабельные дизассемблеры вроде CV.EXE из комплекта MASM требуют подавать им готовые файлы и не позволяют нахально "влезать" на диск или прямо в память компьютера. Для тех, кому поневоле придется пользоваться старым вариантом DEBUG.EXE, некоторые неизвестные ему коды показаны в приведенной ниже таблице. Ее первый столбец содержит первый байт команды, который отладчик представляет как аргумент инструкции DB (7.01-01) в отдельной строке. Следующие байты, как правило, дизассемблируются неверно, но по коду первого и второго байтов (в первом и втором столбцах таблицы) смысл операции удается понять. Часто этого бывает достаточно. При необходимости по ссылке или по названию команды, указанным в четвертом столбце, можно найти более детальные сведения о ней.

– 187 –

Глава 6: Избранные программы для MS-DOS7

1-байт

2-й байт

Байты

Операция, команда

данных

 

 

 

0F

00

1–3

загрузка регистра задачи (LTR)

0F

01

1–3

операции регистров GDTR, IDTR, MSWR

0F

02

1–3

загрузка прав доступа (LAR)

0F

03

1–3

загрузка размера сегмента (LSL)

0F

05

 

загрузка системных регистров (LOADALL)

0F

2(0–3)

 

MOV CR, MOV DR (7.03-58, примечание 1)

0F

4(0–F)

1–3

копирование по условию (CMOV)

0F

8(0–F)

2

условные переходы в пределах 64 кбайт

0F

9(0–F)

 

установление бита по условию (SET)

0F

A(0,8)

 

PUSH FS, PUSH GS (7.03-69)

0F

A(1,9)

 

POP FS, POP GS (7.03-67)

0F

A2

 

идентификация процессора (CPUID)

0F

A(4–7)

1–2

выдвижение битов (SHLD, SHRD)

0F

B(2,4,5)

0–2

загрузка сегментов (LSS, LFS, LGS)

60

 

 

копирование AX – DI в стек (PUSHA)

61

 

 

выталкивание из стека в AX – DI (POPA)

62

 

3

проверка границ массива (BOUND)

63

 

2

приведение прав доступа (ARPL)

6(4,5)

 

 

префиксы сегментов FS:, GS: (7.02-01)

66

 

 

префикс разрядности операнда (7.02-06)

67

 

 

префикс разрядности адреса (7.02-07)

6(8,A)

 

1–2

загрузка числа в стек (PUSH, 7.03-69)

6(9,B)

 

1–3

умножение (IMUL, примечание к 7.03-25)

6(C,D)

 

 

групповой вывод из порта (INSB, INSW)

6(E,F)

 

 

групповая запись в порт (OUTSB, OUTSW)

8(C,E)

E(0–F)

 

MOV FS, MOV GS (7.03-58, примечание 2)

C(0,1)

E(0–7)

1

SHL bl,0f, SHL bx,0f (7.03-82)

C(0,1)

E(8–F)

1

SHR bl,0f, SHR bx,0f (7.03-83)

6.05-19 Отладчик DEBUG.EXE: команда "Write"

Команда "Write" (= записать) записывает код из памяти компьютера на логический диск либо в виде файла, либо просто в заданные сектора диска. В командной строке отладчика DEBUG.EXE вызов команды "Write" задается буквой "W". Вот пример вызова команды "Write" для записи в файл:

W 0100

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

– 188 –

Глава 6: Избранные программы для MS-DOS7

(6.05-01). Если вместо полного адреса задано только смещение, то сегментный адрес будет взят из регистра CS:. Если адрес вообще не указан, то по умолчанию данные считываются из памяти начиная с адреса CS:0100. Длина записываемого фрагмента, отсчитываемая от начального адреса, должна быть заранее загружена в регистры CX (младшие два байта длины файла) и BX (старшие два байта).

Предполагается, что имя файла уже определено предшествовавшей процедурой загрузки или командой "Name" (6.05-12), и что с тех пор сегментный адрес в регистре DS: не изменился. Если имя файла задано без указания пути, то файл будет создан в текущем каталоге текущего диска. Если файл с таким же именем в каталоге назначения уже существует, то он будет перезаписан без предупреждения. Отладчик DEBUG.EXE отказывается записывать файлы с суффиксами *.HEX и *.EXE, потому что такие файлы должны иметь заголовок, который DEBUG.EXE автоматически формировать не может. Впрочем, если Вы уверены в себе, то файл несложно переименовать потом.

Для осуществления записи в сектора логического диска в строке вызова команды "Write" должны быть указаны четыре обязательных параметра, например:

W 0100 0 0 1

Здесь первый параметр указывает стартовый адрес считывания кода, как и при записи в файл. Второй параметр задает номер логического диска: 0 – диск A:, 1 – диск B:, 2 – диск C: и т.д. Третий параметр это шестнадцатеричный номер сектора, с которого следует начинать запись, четвертый параметр шестнадцатеричное количество записываемых секторов. Длина записываемого фрагмента данных зависит только от количества секторов, содержимое регистров BX:CX не учитывается. Запись в физические сектора за пределами логических дисков командой "W" осуществить нельзя.

Примечание 1: если возникает необходимость вывести исполняемый код в файл из области PSP (A.07-1), то сначала следует либо переместить код в другую область памяти, либо перенаправить запись имени в

безопасное место путем изменения сегментного адреса в регистре DS:. Только после этого можно объявлять имя файла командой "Name" и выполнять запись командой "Write" (пример в разделе

9.08).

6.05-20 Отладчик DEBUG.EXE: команда "Allocate"

Команда "Allocate" (= выделить) обращается к драйверу отображаемой памяти EMM386.EXE (5.04-02, 8.03-59) с запросом об образовании в расширенной памяти, за границей 1088 кбайт, выделенной области адресного пространства и присвоении ей номерной ссылки (handle) – двухбайтового шестнадцатеричного числа,

– 189 –

Глава 6: Избранные программы для MS-DOS7

посредством которого на эту область можно ссылаться. Чтобы такую операцию провести, нужно, во-первых, иметь компьютер с объемом памяти более одного мегабайта и, во-вторых, заранее загрузить драйвер EMM386.EXE. В командной строке отладчика DEBUG.EXE вызов команды "Allocate" задается буквами "XA", например:

XA 1A

В строке вызова команды "Allocate" должен быть один обязательный параметр: запрашиваемый размер выделяемой области, выраженный в количестве логических страниц, по 16 кбайт каждая. В показанном примере запрошен размер области 1Ah, то есть 26 логических страниц. Отладчик DEBUG.EXE в ответ сообщает, например: "Handle created 0006" (= для ссылок выделен номер 0006h). Логические страницы памяти нумеруются последовательно, так что показанная команда "XA 1A" создает область, содержащую логические страницы с номерами от 00h до 19h. Чтобы получить доступ к этим страницам памяти, нужно еще отобразить логические страницы на физическое адресуемое пространство с помощью команды "Map" (6.05-22).

6.05-21 Отладчик DEBUG.EXE: команда "Deallocate"

Команда "Deallocate" (= расформировать) обращается к драйверу отображаемой памяти EMM386.EXE (5.04-02, 8.03-61) с запросом о расформировании ранее выделенной области расширенной памяти. Такой запрос имеет смысл только на компьютерах с объемом памяти свыше одного мегабайта, когда драйвер EMM386.EXE заранее установлен, и когда области памяти, которую надлежит расформировать, уже присвоена номерная ссылка (handle). В командной строке отладчика DEBUG.EXE вызов команды "Deallocate" задается буквами "XD", например:

XD 0006

В командной строке вызова команды "Deallocate" должен быть один обязательный параметр: номерная ссылка (handle), присвоенная той выделенной области, которую надлежит расформировать. В данном примере будет расформирована выделенная область расширенной памяти, которой была присвоена номерная ссылка 0006h. Отладчик DEBUG.EXE ответит: "Handle 0006 deallocated" (= номерная ссылка 0006h аннулирована). Занятое выделенной областью адресное пространство будет считаться свободным. Доступ к логическим страницам памяти в расформированной области утрачивается.

– 190 –

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]