ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
Часть 2 TDeb 3.0 #2-3 = 1 = Глава 9. Выражения................................................6 Выбор языка для вычисления выражения............................6 Адреса кода, адреса данных и номера строк.......................7 Доступ к идентификаторам вне текущей области действия...........7 Синтаксис переопределения области действия......................9 Переопределение области.........................................9 Некоторые замечания по переопределению области действия........12 Переопределение области действия в программах Паскаля..........12 Некоторые замечания по переопределению области действия........14 Область действия и DLL.........................................15 Неявная область действия при вычислении выражений..............16 Списки байт....................................................16 Выражения языка Си.............................................17 Идентификаторы языка Си........................................17 Регистровые псевдопеременные языка Си..........................18 Форматы констант и чисел языка Си..............................19 Символьные строки и ESC-последовательности языка Си............20 Операции языка Си и старшинство операций.......................20 Выполнение в программе функций на Си...........................21 Выражения языка Си с побочными эффектами.......................22 Ключевые слова языка Си и преобразование типов.................22 Выражения языка Паскаль........................................23 Идентификаторы Паскаля.........................................23 Константы Паскаля и формат чисел...............................23 Строки Паскаля.................................................24 Операции Паскаля...............................................25 Соглашения Паскаля по вызовам процедур и функций...............25 Выражения Ассемблера...........................................26 Идентификаторы Ассемблера......................................26 Константы Ассемблера...........................................26 Операции Ассемблера............................................28 Управление форматом............................................28 Глава 10. Объектно-ориентированная отладка для Паскаля и C++...........................................................30 Отладка объектно-ориентированных программ Турбо Паскаля........30 Окно Hierarchy.................................................31 Области списка типов объектов и классов........................31 Локальное меню области области списка типов объектов и классов.......................................................32 Команда Inspect................................................32 Команда Tree...................................................32 Область дерева иерархии........................................33 Локальные меню области дерева иерархии.........................33 Локальное меню области дерева порождающих классов..............34 Окно Object Type/Class Inspector...............................35 Локальное меню окна Object Type/Class Inspector................36 Область полей данных объекта (верхняя).........................36 Область методов объекта (нижняя)...............................37 Окно Object/Class Instance Inspector...........................38 Локальное меню окна Object/Class Instance Inspector............39 Средняя и нижняя область.......................................41 Глава 11. Отладка на уровне Ассемблера...........................42 Когда недостаточно отладки на уровне исходного кода............42 TDeb 3.0 #2-3 = 2 = Окно CPU.......................................................43 Область кода...................................................45 Дисассемблер...................................................45 Локальное меню области кода....................................47 Команда Goto...................................................47 Команда Origin.................................................47 Команда Follow.................................................47 Команда Caller.................................................48 Команда Previous...............................................48 Команда Search.................................................48 Команда View Source............................................49 Команда Mixed..................................................49 Команда New CS:IP..............................................50 Команда Assemble...............................................50 Команда I/O....................................................50 Команда In Byte................................................50 Команда Out Byte...............................................51 Команда Read Word..............................................51 Команда Write Word.............................................51 Область регистров и флагов.....................................52 Локальное меню области регистров...............................52 Область селектора..............................................55 Область данных.................................................57 Локальное меню области данных..................................58 Область стека..................................................63 Ассемблер......................................................65 Переопределения размера адреса операнда........................65 Память и непосредственные операнды.............................65 Переопределение размера данных в операндах.....................66 Строковые инструкции...........................................67 Окно Dump......................................................67 Окно Registers.................................................68 Глава 12. Сопроцессор 80х87 и эмулятор...........................69 Сопроцессор 80х87 или эмулятор?................................69 Окно Numeric Processor.........................................69 Область регистров..............................................71 Локальное меню области регистров...............................71 Область управления.............................................73 Локальное меню области управления..............................73 Область состояния..............................................74 Локальное меню области состояния...............................74 Глава 13. Команды Турбо отладчика................................75 Оперативные клавиши............................................75 Команды, доступные из основного меню...........................80 Меню Ё (системное меню)........................................80 Меню File (Файл)...............................................81 Меню Edit (Редактирование).....................................82 Меню View (Обзор)..............................................82 Меню Run (Выполнение)..........................................84 Меню Breakpoints (Точки останова)..............................86 Меню Data (Данные).............................................86 Меню Options (Параметры).......................................86 Меню Window (Окно).............................................88 TDeb 3.0 #2-3 = 3 = Меню Help (Справка)............................................89 Команды локальных меню.........................................90 Локальное меню окна Breakpoints (Точки останова)...............90 Меню окна CPU (ЦП).............................................92 Область кода...................................................92 Область селектора..............................................93 Область данных.................................................94 Область флагов.................................................95 Область стека..................................................97 Окно Dump (Дамп)...............................................98 Меню окна Execution History....................................98 Область инструкций.............................................98 Область регистрации нажатий клавиш.............................99 Окно File (Файл)...............................................99 Локальное меню окна Log (Регистрация).........................100 Окно Module (Модуль)..........................................102 Окно Windows Messages.........................................103 Область выбора окна...........................................104 Область класса сообщений......................................105 Область сообщений.............................................105 Окно Clipboard................................................106 Окно Numeric Proseccor (Сопроцессор)..........................106 Область регистров.............................................107 Область состояния.............................................107 Область управления............................................107 Окно Hierarchy (Иерархия).....................................107 Область списка типов объектов/классов.........................108 Область дерева иерархии.......................................109 Область дерева порождающих объектов/классов...................109 Меню окна Registers (Регистры)................................109 Окно Stack (Стек).............................................110 Окно Variables (Переменные)...................................110 Область локальных идентификаторов.............................110 Окно Watches (Просмотр).......................................112 Окно Inspector (Проверка).....................................113 Окно проверки типа объекта/класса.............................113 Окно проверки экземпляра объекта..............................115 Области текста................................................115 Области списков...............................................117 Команды в окнах подсказки.....................................118 Клавиатурные команды диалогового окна Таблица 13.4.......118 Команды перемещения окна......................................119 Трафаретные символы, используемые при поиске..................119 Полное дерево меню............................................120 Глава 14. Отладка программы.....................................122 Когда что-то не работает......................................122 Стиль отладки.................................................123 Полное выполнение.............................................123 Последовательное тестирование.................................123 Типы ошибок...................................................124 Общие ошибки..................................................124 Скрытые эффекты...............................................124 Предположения об инициализации данных.........................124 TDeb 3.0 #2-3 = 4 = Не забывайте об очистке.......................................125 "Забор и столбы"..............................................125 Ошибки, специфические для языка Си............................125 Использование неинициализированных локальных переменных.......126 Не следует путать = и ==......................................126 Не следует путать старшинство операций........................127 Неверные арифметические действия с указателями................127 Не забывайте о расширении по знаку............................127 Помните об усечении...........................................129 Использование точки с запятой.................................129 Макрокоманды с побочными эффектами............................129 Повторение имен локальных динамических переменных.............129 Неправильное использование динамических локальных переменных...................................................130 Функция возвращает неопределенное значение....................130 Неправильное использование ключевого слова break..............131 Код, не приводящий к результату...............................131 Ошибки, специфические для Паскаля.............................132 Инициализированные переменные.................................132 Неправильная работа с указателями.............................132 Неправильное использование области действия...................133 Неправильное использование точки с запятой....................134 Функция возвращает неопределенное значение....................135 Уменьшение значения переменных размером в байт или слово......136 Игнорирование границ и особые случаи..........................136 Ошибки диапазона..............................................137 Ошибки, специфические для Ассемблера..........................138 Программист забывает о возврате в DOS.........................138 Программист забывает об инструкции RET........................139 Генерация неверного типа возврата.............................139 Неправильный порядок операндов................................139 Программист забывает о стеке или резервирует маленький стек...139 Вызов подпрограммы, которая портит содержимое нужных регистров....................................................140 Ошибки при использовании условных переходов...................140 Неверное понимание работы префикса REP........................140 Нулевое содержимое CX и работа с целым сегментом..............140 Неправильная установка флага направления......................141 Ошибки при повторении команд сравнения строк..................141 Ошибки при назначении сегмента строк..........................141 Неправильное преобразование из байта в слово..................141 Использование нескольких префиксов............................142 Необязательные операнды в командах обработки строк............142 Уничтожение содержимого регистра при умножении................142 Ошибки, связанные с изменением содержимого регистров..........143 Изменение состояния флага переноса............................143 Программист долго не использует флаги.........................143 Смешение операндов в памяти и непосредственных операндов......143 Ошибки, связанные с возвратом в начало сегмента...............143 Сохранение содержимого регистров при обработке прерываний.....144 Игнорирование групп в таблицах операндов и данных.............144 Проверка......................................................145 Проверка граничных условий и случаи ограничения...............145 TDeb 3.0 #2-3 = 5 = Ввод ошибочных данных.........................................145 Отсутствие входных данных.....................................145 Отладка, как часть процесса создание программы................145 Пример сеанса отладки.........................................147 Сеанс отладки программы на языке Си...........................147 Поиск ошибок..................................................147 Разработка плана действий.....................................148 Запуск Турбо отладчика........................................148 Проверка......................................................149 Окно Watch....................................................151 Диалоговое окно Evaluate/Modify...............................151 Эврика!.......................................................151 Сеанс отладки с использованием программы на Паскале...........153 Поиск ошибок..................................................154 Выбор стратегии поиска ошибок.................................155 Запуск Турбо отладчика........................................155 Перемещение по программе......................................157 Диалоговое окно Evaluate/Modify...............................158 Проверка......................................................158 Выражения просмотра...........................................159 Следующая ошибка..............................................160 Глава 15. Виртуальная отладка с использованием процессора 80386........................................................162 Аппаратные средства, необходимые для виртуальной отладки......162 Установка драйвера устройства для виртуального отладчика......162 Запуск виртуального отладчика.................................163 Отличия обычной и виртуальной отладки.........................166 Замечания относительно возможных проблем......................166 Сообщения об ошибках TD386....................................167 Сообщения об ошибках TDH386.SYS...............................169 Глава 16. Отладка в защищенном режиме с использованием TD386........................................................170 Аппаратура, необходимая для использования отладчика TD286.....170 Установка отладчика для защищенного режима....................170 Запуск отладчика для защищенного режима.......................171 Отличия Турбо отладчика и отладчика для защищенного режима....171 Отладка программ, использующих дополнительную память..........171 Выполнение TD286 на разных машинах............................171 TDeb 3.0 #2-3 = 6 = Глава 9. Выражения ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Выражения могут включать в себя идентификаторы вашей прог- раммы (то есть имена переменных и подпрограмм), а также константы и операции одного из поддерживаемых языков (Си, Паскаля или Ас- семблера). Турбо отладчик может вычислять выражения и сообщать вам зна- чение результата. Выражения можно также использовать для ссылки на элементы данных в памяти, значение которых вы хотите узнать. Выражение можно вводить в ответ на любую подсказку, в которой запрашивается значение адреса памяти. (Заметим, что в различных языках выражения вычисляются по-разному.) Для вычисления значения введенного выражения можно использо- вать команду основного меню DataіEvaluate/Modify (ДанныеіВычисле- ние/Модификация). Эту команду можно также использовать, как прос- тейший калькулятор, а также для проверки значений объектов данных в программе. В данной главе мы расскажем вам о том, каким образом Турбо отладчик определяет, какой язык нужно использовать для вычисления выражения, и как задать использование конкретного языка. Мы опи- шем элементы выражений, которые являются общими для всех языков, такие, как номера исходных строк и доступ к регистрам процессора. Затем мы опишем компоненты, которые входят в выражение на любом языке, включая константы, переменные программы, строки и опера- ции. Для каждого языка мы перечислим также поддерживаемые Турбо отладчиком операции и опишем синтаксис выражений. Полное описание выражений Си, Паскаля или Ассемблера содер- жится в руководствах пользователя и справочных руководствах по соответствующим языкам. (см. Borland C++ Getting started, Borland C++ Programmers Guide, Turbo Pascal Users Guide, Turbo Pascal Reference Guide, Turbo Assembler Reference Guide). Выбор языка для вычисления выражения ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик обычно определяет, какой язык нужно использо- вать для вычисления выражения, на основе расширения имени исход- ного файла в текущем модуле. Это тот модуль, в котором останови- лась ваша программа. Этот выбор можно отменить с помощью команды OptionsіLanguage (ПараметрыіЯзык) и открытия диалогового окна Expression Language (Язык для выражений), в котором вы можете с помощью многопозиционного переключателя выбрать один из поддержи- ваемых языков (Паскаль, Си или Ассемблер). Если вы выберете зна- чение Source (Исходный), то выражения вычисляются в соответствии с языком исходного файла (если Турбо отладчик не может определить этот язык, он использует правила языка Ассемблера). Обычно Турбо отладчик сам определяет используемый язык. Од- TDeb 3.0 #2-3 = 7 = нако, иногда полезно задать язык явным образом, например, если вы отлаживаете вызываемый из других языков модуль Ассемблера. Явно задав использование для вычисления выражений конкретного языка, вы можете обращаться к данным так, как это делается в соответс- твующем языке, даже если в текущем модуле используется другой язык. Иногда удобно интерпретировать выражение или переменную та- ким образом, как если бы оно было написано на другом языке. Нап- ример, при отладке программы Паскаля для изменения значения байта в строке удобнее использовать соглашения Си или Ассемблера. Если при запуске Турбо отладчика начальный выбор языка кор- ректен, то при использовании соглашений других языков трудностей не будет. Турбо отладчик сохраняет информацию о исходном языке и выполняет соответствующее преобразование и запись данных. Если язык не определен однозначно, Турбо отладчик использует Ассемб- лер. Даже если вы ошибочно зададите при входе в Турбо отладчик неверный язык, он все равно сможет получить некоторую информацию о языке на основе таблицы идентификаторов и исходного модуля. Од- нако при некоторых обстоятельствах это может привести к тому, что Турбо отладчик будет записывать данные некорректно. Адреса кода, адреса данных и номера строк ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Обычно, когда нужно получить доступ к переменной или имени подпрограммы в вашей программе, вы просто вводите ее имя. Однако можно также вводить указатель, при вычислении которого получается указатель на память, или задавать адреса кода в виде номеров ис- ходных строк, указывая перед номером строки символ #, например, #123 (только для Си и C++). В следующем разделе рассказывается, как можно обращаться к идентификаторам, находящимся вне текущей области действия. Конечно, с помощью обычного синтаксиса вида "сегмент:смеще- ние" вы можете задать шестнадцатиричный адрес: ЪДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДї і Язык і Формат і Пример і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДґ і Си і Oxnnnn і Ox1234:Ox0010 і і Паскаль і $nnnn і $1234:0010 і і Ассемблер і nnnnh і 1234h:0B234h і АДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДЩ Доступ к идентификаторам вне текущей области действия ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Область, в которой Турбо отладчик ищет идентификатор, назы- вается областью действия этого идентификатора. Доступ к идентифи- TDeb 3.0 #2-3 = 8 = каторам, лежащим за пределами текущей области действия, представ- ляет собой сложное понятие, глубоко разбираться в котором в боль- шинстве случаев использования отладчика нет необходимости. Обычно Турбо отладчик ищет входящий в выражение идентифика- тор точно так же, как это делает соответствующий компилятор. Нап- ример, компилятор языка Си ищет его сначала в текущей функции, затем в текущем модуле (статический идентификатор), а затем ищет глобальный идентификатор. Компилятор Турбо Паскаля ищет идентифи- катор сначала в текущей процедуре или функции, затем во "внеш- ней" подпрограмме (если данная (активная) область действия вложе- на в другую), затем в разделе реализации (inplementation) текущего модуля, и, наконец, выполняет поиск глобального иденти- фикатора. Если Турбо отладчик не может найти идентификатор, используя данные методы, то он ищет его во всех других модулях, пытаясь найти соответствие среди статических идентификаторов. Это позво- ляет вам ссылаться на идентификаторы в других модулях, не указы- вая явно имени модуля. Если вы хотите указать Турбо отладчику, что идентификатор нужно искать в каком-то конкретном месте, то при указании имени идентификатора можно задать имя модуля, файл в модуле и подпрог- рамму. Вы можете получить доступ к любому идентификатору програм- му, значение которого определено, даже к тем идентификаторам, ко- торые являются локальными для процедуры или функции и имена кото- рых входят в конфликт с другими идентификаторами. TDeb 3.0 #2-3 = 9 = Синтаксис переопределения области действия ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В зависимости от используемого языка, для переопределения области действия идентификатора с данным именем используются разные символы. - В Си, С++ и Турбо Ассемблере для переопределения области действия используется обычно символ #. - В Паскале с этой целью можно использовать точку (.). Выражение с уточненным идентификатором можно вводить везде, где допустимо выражение, включая: - диалоговое окно Evaluate/Modify; - окно Watches; - диалоговое окно DataіInspector; - диалоговое окно, выводимое командой локального меню Goto или окно Module (когда вы хотите перейти на адрес исходно- го кода). Переопределение области действия в программах Си, С++ и Ассемблера ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для разделения компонентов области действия используйте сим- вол #. Таким образом, для переопределения области действия использу- ется следующий синтаксис (в квадратные скобки заключены необяза- тельные элементы): [#модуль[#имя_файла]]#номер_строки[#номер_переменной] или [#модуль[#имя_файла]][#имя_функции]#имя_переменной Примечание: Переопределение области действия не дейс- твуют для регистровых переменных. Если вы не задаете модуль, то подразумевается текущий мо- дуль. Например, в окне Watches вы можете для переменной программы TDDEMO nlines ввести разные номера строк, чтобы увидеть, как из- меняется ее значение в различных подпрограммах. Чтобы наблюдать за значением переменной на строке 42 и 57, можно ввести в окне Watches следующую запись: TDeb 3.0 #2-3 = 10 = #41#nlines #57#nlines Приведем некоторые примеры допустимых выражений для иденти- фикаторов с переопределением области действия (каждой допустимой комбинации элементов, которые можно использовать для переопреде- ления области действия соответствует один пример). В первых 6 примерах показаны различные способы использова- ния номеров строк для генерации адресов и переопределения области действия: #123 (Строка 123 в текущем модуле.) #123myvar1 (Идентификатор myvar1 доступен из строки 123 текущего мо- дуля.) #mymodule#123 (Строка 123 в модуле #mymodule.) #mymodule#123#myvar1 (Идентификатор myvar1 доступен из строки 123 в модуле mymodule.) #mymodule#file#123 (Строка 123 в исходном файле file, который является частью модуля mymodule.) #mymodule#file#123#myvar1 (Идентификатор myvar1 доступен из строки 123 в исходном файле file1, который является частью модуля mymodule.) Следующие 6 примеров показывают различные способы переопре- деления области действия переменной с использованием имени моду- ля, файла или функции: #myvar2 (То же, что и myvar2 без #.) #myfunc#myvar2 (Переменная myvar2 доступна из подпрограммы myfunc.) TDeb 3.0 #2-3 = 11 = #mymodule#myvar2 (Переменная myvar2 доступна из модуля mymodule.) #mymodule#myfunc#myvar2 (Переменная myfunc доступна из подпрограммы myfunc в мо- дуле mymodule.) #mymodule#file2#myvar2 (Переменная myvar2 доступна из файла file2, являющегося частью модуля mymodule.) #mymodule#file2#myfunc#myvar2 (Переменная myvar2 доступна из подпрограммы myfunc, опре- деленной в файле file2, который входит в модуль mymodule.) Следующие 4 примера показывают переопределения области дейс- твия для классов, объектов и функций-элементов С++: AnObject#AMemberVar Элемент данных AMemberVar доступен в объекте AnObject, дос- тупном в текущей области действия. AnObject#AMemberF Функция-элемент AMemberF доступна в объекте AnObject, дос- тупном в текущей области действия. #AModule#AnObject#AClass::AMemberVar Элемент данных AMemberVar в классе AClass доступен в объекте AnObject, доступном в модуле AModule. Если при отладке программы на языке С++ вы хотите проверить функцию с переопределенным именем, то для этого в соответствующем поле ввода просто введите имя функции. Турбо отладчик открывает диалоговое окно Pick a Symbol Name (Выбор имени идентификатора) со списком всех функций с данным именем вместе с их аргументами. Вы можете выбрать то, что вам нужно. TDeb 3.0 #2-3 = 12 = Некоторые замечания по переопределению области действия ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД При переопределении области действия в программах на языках Си, C++, Паскаль или Ассемблер вам могут помочь следующие замеча- ния: 1. Если вы используете имя файла с оператором переопределе- ния области действия, то ему должно предшествовать имя модуля. 2. Если имя файла имеет расширение (.ASM, .C или .CPP), то вы должны указать расширение. Турбо отладчик сам расшире- ние не распознает. 3. Если первым элементом в операторе переопределения области действия является функция, то перед ней не должен указы- ваться символ #. При наличии символа # Турбо отладчик ин- терпретирует имя функции как имя модуля. 4. Любая переменная, к которой вы обращаетесь с помощью пе- реопределения области действия, уже должна быть инициа- лизирована. 5. Если вы пытаетесь получить доступ к динамической локаль- ной переменной, лежащей вне области действия, то в ка- честве части операторе переопределения области действия нужно использовать имя ее функции. 6. Турбо отладчик поддерживает шаблоны и вложенные классы C++. - Область действия шаблона зависит от текущей ячейки в программе. Окна Wathes и Inspector с выражениями шабло- на зависят от текущего объекта, в котором находится программа. - Вложенный класс находится в области действия того клас- са, в который он вложен. Область действия вложенного класса не является для программы глобальной. Переопределение области действия в программах Паскаля ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для разделения компонентов области действия используется точка (.). Для переопределения области действия используется следующий синтаксис (в квадратные скобки заключены необязательные элемен- ты): [модуль.[имя_процедуры]имя_переменной TDeb 3.0 #2-3 = 13 = или [модуль.[объектный_тип.][реализация_объекта.][метод]имя_поля Если вы не задаете модуль, то подразумевается текущий мо- дуль. Далее приведено несколько примеров, которые не включают объ- екты и методы. Каждый пример соответствует одной допустимой ком- бинации элементов, которую вы можете использовать для переопреде- ления области действия. В следующих примерах показаны различные способы переопреде- ления области действия с помощью использования имени процедуры или модуля: AVar Переменная AVar доступна в те- кущей области действия. AProc.AVar Локальная переменная AVar про- цедуры AProc доступна в теку- щей области действия. AUnit.AVar Локальная переменная AVar дос- тупна в модуле AUnit. AUnit.AProc.AVar Переменная AVar доступна в процедуре AProc, которая, в свою очередь, доступна в моду- ле AUnit. Ниже приводятся несколько примеров, включающих объекты и ме- тоды: Instance Реализация Instance доступна в текущей области действия. Instance.AField Поле AFild доступно в реализации Instance, доступной в текущей области действия. AnObjectType.AMethod Метод AMethod досту- пен в типе объекта AnObjectType, доступ- ном в текущей области действия. AnInstance.AMethod Метод AMetod доступен в экземпляре AnInstance, доступном TDeb 3.0 #2-3 = 14 = в текущей области действия. AUnit.AInstance.AFild Поле AFild доступно в экземпляре AInstance, который доступен в модуле AUnit. AUnit.AnObjectType.AMethod Метод AMethod досту- пен в типе AnObjectType, который доступен в модуле AUnit. AUnit.AnObjectType.AMetod.ANestedProc.AVar Локальная переменная AVar доступна в про- цедуре ANestedProc, которая доступна в методе AMethod, кото- рый доступен в типе AnObjectType, кото- рый, в свою очередь, доступен в модуле AUnit. Вы можете вводить такие уточненные идентификаторы выражений в любом месте, где выражение допустимо (в том числе и в окнах просмотра и вычисления (Watch и Evaluate)), например, если вы из- меняете выражение в окне проверки (Inspector) или используете ло- кальное меню в окне Module (Модуль) для перехода (Goto) по адресу метода или процедуры в исходном коде. Некоторые замечания по переопределению области действия ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД При переопределении области действия в программах на языке Паскаль вам могут помочь следующие замечания: 1. Любая переменная, к которой вы обращаетесь с помощью пе- реопределения области действия, уже должна быть инициа- лизирована. 2. Если вы пытаетесь обратиться к локальной переменной, ко- торой нет в текущей области действия, вы должны в качест- ве части оператора переопределения области действия ис- пользовать имя процедуры или функции. 3. В Паскале в качестве части оператора переопределения об- ласти действия вы не можете использовать имя файла. Одна- ко, для изменения языка на Си, в котором это допускается, можно использовать команду OptionsіLanguage (Параметрыі Язык). TDeb 3.0 #2-3 = 15 = Область действия и DLL ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Поскольку TDW одновременно загружает таблицы идентификаторов файла .EXE текущего модуля и его библиотек DLL (к которым он об- ращается и для которых имеется исходный код и таблица идентифика- торов), вы можете не иметь возможности немедленно обратиться к переменным DLL (или к переменным файла .EXE, когда вы находитесь в DLL). TDW сначала ищет переменную в таблице идентификаторов теку- щего модуля или DLL, а затем во всех других таблицах в порядке их загрузки. Если переменная имеет одно и то же имя в нескольких DLL или в файле .EXE и в DLL, то отладчик TDW видит только первый ее экземпляр. Для доступа к таким переменным вы не можете использо- вать синтаксис переопределения области действия. Вместо этого для загрузки соответствующего модуля или DLL нужно использовать кла- вишу F3 или диалоговое окно Load Modules and DLLs (Загрузка моду- лей и библиотек DLL). Отладчик TDW загружает таблицу идентификаторов для: 1. Текущего модуля файла .EXE. 2. Любой явно загружаемой с помощью команды Symbol Load (Загрузка идентификаторов) диалогового окна Load Modules and DLLs (Загрузка модулей и DLL) DLL. 3. Любой DLL, в которую вы вошли из вашей программы. TDeb 3.0 #2-3 = 16 = Неявная область действия при вычислении выражений ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Всякий раз, когда Турбо отладчик вычисляет выражение, он должен определить без явного указания, где в программе находится область действия каждого идентификатора. Во многих языках это имеет существенное значение, так как в процедурах и функциях мо- гут использоваться идентификаторы с теми же именами, что и гло- бальные идентификаторы. Турбо отладчик должен знать, какой именно идентификатор вы имеете в виду. В качестве основы при принятии решения об области действия Турбо отладчик обычно использует текущую позицию курсора. Напри- мер, вы можете задать область действия, которая будет использо- ваться при вычислении выражения, переместив курсор на ту или иную строку в окне Module (Модуль). Это означает, что при смещении курсора с текущей строки, где остановилась ваша программа, вы можете при вычислении выражения получить непредвиденные результаты. Если вы хотите убедиться, что выражения вычисляются в текущей области действия вашей программы, используйте команду локального меню окна Module Origin (Начало), чтобы вернуться к текущему адресу исходного кода. Задать область действия выражения можно также, перемещаясь в области Code (Код) окна CPU (Центральный процессор), устанавливая курсор на подпрог- рамму в окне Stack (Стек) или на имя подпрограммы в окне Variables (Переменные). Списки байт ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В некоторых командах от вас требуется ввести список байт. Это команды локального меню области Data (Данные) окна CPU (Цент- ральный процессор) Search (Поиск) и Change (Изменение) или такие же команды локального меню окна File (Файл), в котором файл выво- дится в шестнадцатиричном виде. Список байт может представлять собой произвольную смесь ска- лярных (без плавающей точки) чисел и строк, в которых использует- ся синтаксис текущего языка (его можно задать командой OptionsіLanguage (ОпцииіЯзык)). И в строках, и в скалярных значе- ниях используется тот же синтаксис, что и в выражениях. Скалярные значения преобразуются в соответствующую последовательность байт. Например, длинное целое (longint) значение Паскаля 123456 преоб- разуется в 4-байтовый шестнадцатиричный эквивалент 56 34 12 00. ЪДДДДДДДДДДДВДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДї і Язык і Список байт іШестнадцатиричные данные і ГДДДДДДДДДДДЕДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДґ і Си і "ab"0x04"c" і 61 62 04 63 і і Паскаль і 'ab'#4'c' і 61 62 04 63 і і Ассемблер і 1234"AB" і 34 12 41 42 і АДДДДДДДДДДДБДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 17 = Выражения языка Си ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик полностью поддерживает синтаксис выражений языка Си. Выражение состоит из смеси операций, строк, переменных и констант. Каждый из этих компонентов описан в одном из следую- щих разделов. Идентификаторы языка Си ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Идентификатор языка Си представляет собой имя элемента дан- ных или подпрограммы в программе. Имя идентификатора должно начи- наться с буквы (a-z или A-Z) или символа подчеркивания (_). Пос- ледующие символы в идентификаторе могут содержать цифры от 0 до 9 или любые из указанных символов. В именах идентификаторов первый символ подчеркивания можно опускать. Если вы вводите имя иденти- фикатора без символа подчеркивания, и этот идентификатор найти не удается, то выполняется его повторный поиск с символом подчерки- вания. Так как обычно компилятор помещает перед именем идентифи- катора символ подчеркивания, вы можете его не добавлять. TDeb 3.0 #2-3 = 18 = Регистровые псевдопеременные языка Си ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик позволяет вам получить доступ к сегментным регистрам с помощью того же метода, что и метод, используемый компилятором языка Си, а именно - с помощью псевдопеременных. Псевдопеременная представляет собой имя переменной, соответствую- щее данному регистру процессора: ЪДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДї і Псевдопеременная і Тип і Регистр і ГДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДґ і _AX і unsigned int і AX і і _AL і unsigned char і AL і і _AH і unsigned char і AH і і і і і і _BX і unsigned int і BX і і _BL і unsigned char і BL і і _BH і unsigned char і BH і і і і і і _CX і unsigned int і CX і і _CL і unsigned char і CL і і _CH і unsigned char і CH і і і і і і _DX і unsigned int і DX і і _DL і unsigned char і DL і і _DH і unsigned char і DH і і і і і і _CS і unsigned int і CS і і _DS і unsigned char і DS і і _SS і unsigned char і SS і і _ES і unsigned char і ES і і і і і і _SP і unsigned int і SP і і _BP і unsigned char і BP і і _DI і unsigned char і DI і і _SI і unsigned char і SI і і і і указатель і і _IP і unsigned int і инструкцийі АДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 19 = Получить доступ к регистрам процессора 80386 позволяют сле- дующие псевдопеременные: ЪДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДї і Псевдопеременная і Тип і Регистр і ГДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДґ і _EAX і unsigned long і EAX і і _EBX і unsigned long і EBX і і _ECX і unsigned long і ECX і і _EDX і unsigned long і EDX і і і і і і _ESP і unsigned long і ESP і і _EBP і unsigned long і EBP і і _EDI і unsigned long і EDI і і _ESI і unsigned long і ESI і і і і і і _FS і unsigned int і FS і і _GS і unsigned int і GS і АДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДЩ Форматы констант и чисел языка Си ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Константы могут быть с плавающей точкой или представлять со- бой целые константы. Если не используется одно из переопределений в соответствии с соглашениями языка Си, то целая константа задается в десятичном виде. ЪДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДї і Формат і Основание і ГДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДґ і цифры і Десятичное і і Oцифры і Восьмеричное і і OXцифры і Шестнадцатиричное і і Oхцифры і Шестнадцатиричное і АДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДЩ Константы имеют обычно тип int (16 бит). Если вы хотите оп- ределить длинную константу (32 бита), то конце числа нужно доба- вить l или L. Например, 123456L. Константа с плавающей точкой содержит десятичную точку и мо- жет использоваться для научного представления, например: 1.234 4.5e+11 TDeb 3.0 #2-3 = 20 = Символьные строки и ESC-последовательности языка Си ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Строки представляют собой последовательность символов, зак- люченную в кавычки (""). В качестве управляющего символа можно также в соответствии со стандартными соглашениями языка Си ис- пользовать также обратную косую черту (\). ЪДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДї і Последовательность і Значение і Символ і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДґ і \\ і і Обратная косая черта і і \a і OX07 і "Звонок" і і \b і OX08 і Обратный пробел і і \f і OX0C і Перевод формата і і \n і OX0A і Новая строка і і \r і OX0D і Возврат каретки і і \t і OX09 і Горизонтальная табуляция і і \v і OX0B і Вертикальная табуляция і і \xnn і nn і Шестнадцатиричное і і і і значение байта і і \nnn і nnn і Восьмеричное значение і і і і байта і АДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Если за обратной косой чертой следует один из перечисленных здесь символов, то этот символ включается в строку без изменения. Операции языка Си и старшинство операций ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В Турбо отладчике используются те же операции, что и в языке Си, и выполняются они в том же порядке. Однако в отладчике имеет- ся одна новая операция, которая не входит в стандартный набор операция языка Си. Это операция ::. Она имеет более высокий прио- ритет, чем любая из операций языка Си, и используется для форма- тирования постоянного дальнего адреса из выражения, которое ей предшествует, и выражения, которое за ней следует. Основные операции выражений: () [] . -> sizeof имеют наивысший приоритет (слева-направо). Унарные операции: * & - ! ~ ++ -- имеют приоритет более низкий, чем основные операции, но более вы- сокий, чем бинарные операции (при группировании справа-налево). Приоритет бинарных операций убывает в соответствии со следующим списком (операции с равным приоритетом содержатся на одной стро- ке): TDeb 3.0 #2-3 = 21 = высший * / % + - >> << < > <= >= == != & ^ і && низший іі Единственная тернарная операция ? имеет более низкий приори- тет, чем любая из двоичных операций. Операторы присваивания имеют более низкий, чем тернарная операция и одинаковый приоритет и группируются справа-налево: = += -= /= %= >>= <<= &= ^= і= Выполнение в программе функций на Си ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Функции в выражениях Си можно вызывать точно также, как это делается в исходном коде. Турбо отладчик выполняет код вашей программы с теми аргументами функции, которые вы задаете. Это мо- жет оказаться очень полезным для быстрой проверки поведения напи- санной функции. Ее можно повторно вызывать с различными аргумен- тами и проверять, возвращает ли она корректное значение. Если ваша программа содержит следующую функцию, которая воз- водит число в степень (x в степени y): long power(int x, int y) { long temp = 1; while (y--) temp *= x; return(temp); } TDeb 3.0 #2-3 = 22 = то в следующей таблице показаны результаты вызова данной функции с различными аргументами: ЪДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДї і Выражение Си і Результат і ГДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і power(3,2)*2 і 18 і і 25 + power(5,8) і 390650 і і power(2) і Ошибка (пропу- і і і щен аргумент) і АДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Выражения языка Си с побочными эффектами ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Побочные эффекты имеют место, когда вы вычисляете выражение языка Си, которое в процессе вычисления изменяет значение элемен- та данных. В некоторых случаях побочные эффекты являются жела- тельными и используются преднамеренно для модификации значения переменной программы. В других случаях желательно соблюдать осто- рожность и избегать их, поэтому важно понимать, когда может воз- никнуть побочный эффект. Операция присваивания (=, += и т.д.) изменяет значение эле- мента данных, расположенного слева от операции. Операции увеличе- ния и уменьшения (++ и --) изменяют значения элементов данных, которые им предшествуют или следуют за ними, в зависимости от то- го, используются они как префиксные, или как постфиксные опера- ции. Менее очевидный тип побочных эффектов может иметь место, когда вы выполняете функцию, являющуюся частью программы. Напри- мер, если вы вычисляет выражение Си: myfunc(1, 2, 3) + 7 то, если функция myfunc изменила значение одной из переменных программы, ваша программа может в дальнейшем вести себя неверно. Ключевые слова языка Си и преобразование типов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик позволяет вам выполнять приведение указателей также, как это делалось бы в программе на языке Си. Приведение типа состоит из объявления типа данных языка Си в круглых скоб- ках. Оно должно следовать перед выражением, при вычислении кото- рого получается указатель на память. Преобразование типа полезно использовать, если вы хотите проверить содержимое ячейки памяти, на которую ссылается дальний адрес, сгенерированный с использованием операции ::. Например: TDeb 3.0 #2-3 = 23 = (long far *)Ox3456::0 (char far *)_ES::_BX Преобразование типа можно использовать для доступа к пере- менной программы, для которой информация о типе отсутствует (что может произойти при компиляции модуля без включения информации для отладки). Вместо того, чтобы выполнять перекомпиляцию и пере- компоновку, можно просто перед именем переменной указать приведе- ние типа (то есть присвоить тип явным образом). Например, если ваша переменная iptr представляет собой ука- затель на целое, вы можете проверить целое значение, на которое она указывает, вычислив выражение Си: *(int *)iptr При формировании преобразования типов в Турбо отладчике мож- но использовать следующие ключевые слова: char float far int double huge short unsigned struct long near union enum Выражения языка Паскаль ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик, за исключением конкатенации строк и операций над множествами, поддерживает синтаксис выражений Паскаля. Выра- жение представляет собой смесь операций, строк, переменных и констант. В следующих разделах описывается каждый из образующих выражение компонентов. Идентификаторы Паскаля ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Идентификаторы в Паскале представляют собой определенные пользователем имена элементов данных или подпрограмм вашей прог- раммы. Имя идентификатора Паскаля может начинаться с буквы (a - z, A - Z) или символа подчеркивания. Последующие символы в имени могут содержать цифры (от 0 до 9) и подчеркивания, а также буквы. Обычно идентификаторы подчиняются правилам области действия Паскаля, при этом "вложенные" локальные идентификаторы переопре- деляют другие идентификаторы в том же имени. Вы можете переопре- делить данную область действия, если хотите получить доступ к идентификаторам в других областях. Более подробно это описывается в разделе "Доступ к идентификаторам вне текущей области дейс- твия". Константы Паскаля и формат чисел ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Константы могут быть либо вещественными (с плавающей точ- TDeb 3.0 #2-3 = 24 = кой), либо целыми. Отрицательные константы начинаются со знака минуса (-). Если число содержит десятичную точку или символ e, что обозначает экспоненту, то это вещественное число. Например: 123.4 456e34 123.45e-5 Константы целого типа являются десятичными, если они не на- чинаются со знака доллара ($), что означает шестнадцатиричную константу. Десятичные целые константы могут принимать значения в диапазоне от 2137483648 и 2147483647. Шестнадцатиричные константы должны лежать в диапазоне от $00000000 до $FFFFFFFF. Строки Паскаля ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Строка представляет собой просто группу символов, заключен- ных в одиночные кавычки, например: 'abc' Указав перед десятичным управляющим символом символ #, можно включить в строку управляющие символы, например: 'def'#7'xyz' TDeb 3.0 #2-3 = 25 = Операции Паскаля ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик поддерживает все операции, использующиеся в выражениях Паскаля. Унарные операции имеют старший и одинаковый приоритет. @ Получает адрес идентификатора. ^ Содержимое указателя. not Поразрядное дополнение. typeid Приведение типа. + Унарный плюс (положительное значение). - Унарный минут (отрицательное значение). Бинарные операции имеют более низкий приоритет, чем унарные операции. Перечислим их в порядке убывания приоритета: * \ div mod and shl shr in + - or xor < <= > >= = <> Операция присваивания := имеет низший приоритет. Для вашего удобства она возвращает значение (как в языке Си). Соглашения Паскаля по вызовам процедур и функций ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В выражениях Турбо Паскаля можно ссылаться на процедуры и функции. Например, предположим, что вы описали функцию с именем HalfFunc, которая делит целое значение на 2: function HalfFunc(i: integer) real); Затем вы можете выбрать команду DataіEvaluate/Modify (Данные іВычисление/Модификация) и вызвать функцию HalfFunc следующим об- разом: HalfFunc(3) HalfFunc(10) = HalfFunc(10 div 3) Можно также вызывать процедуры (но, конечно, не в выражени- ях). Когда вы вводите просто имя процедуры или функции, Турбо от- ладчик выводит ее адрес и описание. Чтобы вызвать процедуру или функцию, которая не имеет параметров, укажите после имени функции скобки, например: MyProc() Вызывает MyProc. MyProc Сообщает адрес MyProc и т.д. MyFunc=5 Сравнивает адрес MuFunc c 5. MyFunc()=5 Вызывает MyFunc и сравнивает возвращаемое значение с 5. TDeb 3.0 #2-3 = 26 = Выражения Ассемблера ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик поддерживает полный синтаксис выражений Ас- семблера. Выражение состоит из смеси операций, строк, переменных и констант. Каждый из этих компонентов описывается в следующем разделе. Идентификаторы Ассемблера ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Идентификаторы представляют собой определенные пользователем имена элементов данных и подпрограмм в вашей программе. Имя иден- тификатора Ассемблера начинается с буквы (a - z, A - Z) или одно- го из следующий символов: @, ?, _, $. Последующие символы в иден- тификаторе могут содержать цифры (0 - 9) или любой из указанных символов. В качестве первого символа имени идентификатора (но не внутри имени) можно также использовать точку. Специальный идентификатор $ ссылается на текущий адрес прог- раммы, определяемый парой регистров CS:IP. Константы Ассемблера ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик обеспечивает работу с константами всех типов, которые используются в Ассемблере (byte, word, длинные, состав- ные, с плавающей точкой, вещественные, с двойной и расширенной точностью). Константа с плавающей точкой содержит десятичную точку и может использовать научное десятичное представление. 1.234 4.5e+11 Если не используется одно из соглашений Ассемблера по пере- определению основания, то целочисленные константы являются шест- надцатиричными. ЪДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і Формат і Основание і ГДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і цифрыH і Шестнадцатиричное і і цифрыO і Восьмеричное і і цифрыQ і Восьмеричное і і цифрыD і Десятичное і і цифрыB і Двоичное і АДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Шестнадцатиричное число всегда должно начинаться с цифры (0 - 9). Если вы ходите начать число с одной из букв (A - F), то пе- ред ним должен следовать 0. Примечание: Если вы хотите закончить шестнадцатиричное TDeb 3.0 #2-3 = 27 = число символом D или B, то, чтобы избежать неоднозначности, нужно добавить H. TDeb 3.0 #2-3 = 28 = Операции Ассемблера ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик поддерживает большинство операций, использую- щиеся в Ассемблере. Старшинство этих операций соответствует стар- шинству операций, принятому в Ассемблере: xxx PTR (BYTE PTR...) .(селектор элемента структуры) :(переопределение сегмента) OR XOR AND NOT EQ NE LT LE GT GE + - * / MOD SHR SHL Унарный -, Унарный + OFFSET SEG () [] Переменные можно изменять с помощью операции присваивания =. Например: a = [BYTE PTR DS:4] Управление форматом ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Когда вы указываете выражение, которое должно выводиться на экран, Турбо отладчик выводит его в формате, основывающемся на типе данных, которые в нем используются. Турбо отладчик игнориру- ет управление форматом, неверное для данного типа данных. Если вы хотите изменить используемый по умолчанию формат вы- вода данных на экран, поместите в конце выражения запятую и нео- бязательный счетчик повторения, за которым указывается необязате- льная буква формата. Счетчик повторения нужно задавать только для массивов. TDeb 3.0 #2-3 = 29 = Символы, управляющие форматом вывода Ассемблера, описываются с следующей таблице: ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Идентификатор Формат ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД c Символ или строка выводятся на экран в виде необ- работанных символов. Обычно непечатаемые символы выводятся в виде управляющих символов или в чис- ловом формате. Этот параметр приводит к тому, что при выводе символов будет использоваться полный набор символов дисплея IBM. d Целое число выводится в виде десятичного значе- ния. f[#] Формат с плавающей точкой с заданным числом цифр. Если вы не задаете число цифр, то используется столько цифр, сколько необходимо. m Выражение со ссылкой на память выводится в виде шестнадцатиричных байт. md Выражение со ссылкой на память выводится в виде десятичных байт. P Выводится необработанное значение указателя, по- казывающее сегмент, как имя регистра (если это возможно). Показывается также объект, на который указатель ссылается. Если управление форматом не задано, то это используется по умолчанию. s Выводится массив или указатель на массив символов (строка, заключенная в кавычки). Строка заверша- ется нулевым символом. x или h Целое выводится в виде шестнадцатиричного значе- ния. ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД TDeb 3.0 #2-3 = 30 = Глава 10. Объектно-ориентированная отладка для Паскаля и C++ ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Чтобы удовлетворить потребности развития методов объект- но-ориентированного программирования, принципы которого реализо- ваны в последних версиях таких языков высокого уровня, как Турбо C++ и Турбо Паскаль, Турбо отладчик был также модифицирован для поддержки объектно-ориентированного программирования. Кроме тех расширений, которые позволяют вам выполнять трассировку методов объектов или функций-элементов классов в диалоговом окне Evaluate /Modify (Вычисление/Модификация) и окне Watch (Просмотр), Турбо отладчик версии 3.0 оснащен специальным набором окон и локальных меню, созданных специально для работы с объектными типами и клас- сами. Отладка объектно-ориентированных программ Турбо Паскаля ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Пошаговое выполнение и трассировка вызовов методов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Во время трассировки (клавиша F7) и пошагового выполнения (клавиша F8) Турбо отладчик рассматривает методы в точности так, как если бы они были процедурами или функциями. Клавиша F7 осу- ществляет трассировку исходного кода метода (если этот код досту- пен), тогда как F8 рассматривает вызов метода, словно это один оператор, и "перешагивает" через него. Турбо отладчик правильно управляет поздним связыванием вир- туальных методов: он всегда выполняет и выводит на экран коррект- ный код. В окне стека Турбо отладчика (окно Stack) выводятся на экран имена методов, перед которыми указывается тип объекта, оп- ределяющего метод. TDeb 3.0 #2-3 = 31 = Окно Hierarchy ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В Турбо отладчике предусмотрено специальное окно Hierarchy (Иерархия) для проверки иерархии объектов или классов. Вывести это окно можно по команде меню ViewіHierarchy (ОбзоріИерархия). Й[*]ННННClass HierarchyНННННННННННННННННННН3ННННН[ ][ ]» єDevice і АДДДДДДДДPoint є єGlowGauge і АДДДДДДДДДДRectangle є єHorzArrow і ГДДДДДДДDevice є єHorzBar і АДДДДДДДTextWindowє єLinearGauge іRange є єPoint і АДДДДДДDevice є єRange і ГДДДДДДGlowGauge є єRectangle ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДє єScreen іParents of Device є єTextWindow і іДДДДДДДДДДRange є єVertArrow і АДДДДДДДДДДRectangle є єVertBar і АДДДДДДДДДДPoint є є і АДДДДДДДScreen є ИННННННННННННН<І±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>Ѕ Рис. 10.1 Окно Hierarchy В окне Hierarchy (Иерархия) выводится информация об объект- ных типах или классах, а не об их экземплярах. В левой области выводится список в алфавитном порядке всех типов, используемых в отлаживаемом модуле. В правой области (двух областях, если вы от- лаживаете программу на C++ с множественным наследованием) показа- на иерархия всех объектов или классов (с помощью линейной графи- ки). При этом по левой границе области выводится базовый тип и показываются порожденные им типы ("потомки"). Кроме того показаны все "предки" классов с множественным наследованием. При этом ли- нии показывают отношения между "предками" и "потомками". Примечание: Для перемещения между двумя областями ис- пользуйте клавишу Tab. Области списка типов объектов и классов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В левой области окна иерархии объектов/классов выводится (в алфавитном порядке) список всех типов классов или объектов в те- кущем модуле. Она поддерживает средство инкрементального поиска, что исключает необходимость перемещать курсор по большим спискам типов. Когда полоса подсветки находится в левой области, можно просто начать набирать новое имя искомого типа объекта или клас- са. При каждом нажатии клавиши Турбо отладчик подсвечивает первый тип, соответствующий всем нажатым к этому моменту клавишам. Для того, чтобы открыть окно Inspector (Проверка) для подс- веченного типа объекта или класса, нажмите клавишу Enter. Окна TDeb 3.0 #2-3 = 32 = проверки описаны далее. Локальное меню области области списка типов объектов и классов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для вывода локального меню данной области нажмите клавиши Alt-F10. Вы можете также использовать сокращения (оперативные клавиши), если это разрешено с помощью утилиты TDINST. Данное ло- кальное меню содержит два элемента: Inspect и Tree. ЪДДДДДДДДДДДДДДДДДї Проверка і Inspect і Дерево і Tree і АДДДДДДДДДДДДДДДДДЩ Команда Inspect ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Данная команда выводит для подсвеченного типа объекта/класса окно Inspector (Проверка). Команда Tree ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Данная команда перемещает вас в правую область окна, в кото- рой выведено дерево иерархии объектов, и помещает полосу подсвет- ки на тип, который подсвечен в левой области. TDeb 3.0 #2-3 = 33 = Область дерева иерархии ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В правой области окна Hierarchy выводится дерево иерархии для всех объектов или классов, использующихся в текущем модуле. Отношения "предков" и "потомков" показаны линиями, при этом "по- томки" расположены слева и ниже своих "предков". Чтобы найти объект или класс конкретного типа в сложном де- реве иерархии, перейдите обратно в левую область и используйте средство инкрементального поиска (или поиска по возрастанию). За- тем выберите в локальном меню элемент Tree (Дерево), чтобы перей- ти обратно к дереву иерархии. Соответствующий тип выводится в по- лосе подсветки. При нажатии клавиши Enter для подсвеченного типа объек- та/класса выводится окно Inspector (Проверка). Если вы загрузили программу на языке C++, в которой исполь- зуются классы с множественным наследованием, то выводится третья область - дерево порождающих классов, которая расположена в окне Hierarchy (Иерархия) ниже дерева иерархии. Если исследуемый вами класс имеет нескольких "предков", то, если в локальном меню об- ласти дерева иерархии выбрана команда Parent (Порождающий класс), и для нее установлено значение Yes (Да), то области дерева порож- дающих классов выводится обратное дерево (с сообщением "Parents of Class" - "Порождающие классы для данного класса" в левой гра- нице области). Ниже и правее левой границы выводятся "предки". При этом линиями показаны отношения "предков" и "потомков". Также, как и в области дерева иерархии, для любого класса, выводимого в области дерева порождающих классов, можно открыть окно Inspector (Проверка). Локальные меню области дерева иерархии ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Локальное меню области дерева иерархии содержит только один элемент - Inspect (Проверка). Когда вы его выбираете, для подсве- ченного типа выводится окно проверки типа класса/объекта. Однако, если вы хотите проверить подсвеченный тип, быстрее и проще будет просто нажать клавишу Enter. ЪДДДДДДДДДДДї Проверка і Inspect і АДДДДДДДДДДДЩ Если вы загрузили программу на языке C++, в которой исполь- зуются классы с множественным наследованием, то локальное меню области дерева иерархии содержит два элемента: Inspect и Parents. ЪДДДДДДДДДДДДДДДДДДДДї Проверка і Inspect і Предки і Parents Yes і АДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 34 = Parents - это переключатель, с помощью которого вы можете управлять выводом "предков" класса в области дерева порождающих классов. Его полезно использовать, если проверяемый вами класс имеет множественное наследование. По умолчанию данный переключа- тель имеет значение Yes (Да). Локальное меню области дерева порождающих классов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Область дерева порождающих (родительских) классов, если она присутствует, содержит локальное меню с единственной командой Inspect (Проверка). ЪДДДДДДДДДДДДї Проверка і Inspect і АДДДДДДДДДДДДЩ Работает данная команда аналогично команде Inspect (Провер- ка) локального меню области дерева иерархии, то есть открывает окно Inspector для подсвеченного типа объекта или класса. TDeb 3.0 #2-3 = 35 = Окно Object Type/Class Inspector ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик предоставляет новый тип окна Inspector (Про- верка) с целью позволить вам проверять детали объектного типа. Это окно проверки типов объектов/классов (Object Type/Class Inspector). В данном окне сведена информация о типе объекта, но оно не относится к какому-либо отдельному экземпляру этого типа. ЙНН[*]ННClass LinearGaugeНН4ННН[ ][ ]» єint±Range::Low±±±±±±±±±±±±±±±±±±±±±±^ єint Range::High ° єint Screen::MaxX v є<І°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°>є єclass Range *Range::ctr() є єint Range::GetValue() є єint Range::GetLow() є єint Range::GetHigh() є ИННННННННННННННННННННННННННННННННННННЅ Рис. 10.2 Окно Object Type/Class Inspector Окно делится по горизонтали на две области, в верхней из ко- торых выводится список полей данных типа объекта, а в нижней - список имен методов и (если выбранный метод является функцией) возвращаемый функцией тип. Используйте клавишу горизонтальной та- буляции для переключения между двумя областями окна Object Type/Class Inspector (Проверка типов объектов/классов). Если подсвеченное поле данных является объектным типом или указателем на объектный тип, то нажатие клавиши Enter открывает другое окно проверки типов объектов/классов (Object Type/Class Inspector) для подсвеченного типа. (Это действие идентично выбору элемента Inspect в локальном меню этого окна.) Таким образом, сложная вложенная структура объектов может быстро просматриваться при минимальном количестве нажатий клавиш. Для краткости параметры методов не показываются в окне проверки типов объектов. Для проверки параметров метода перемес- тите подсветку на метод и нажмите клавишу Enter. Появится окно проверки метода/функции (Inspector). Верхняя область окна выводит на экран адрес кода экземпляра типа объекта/класса для выбранного метода и имена и типы всех параметров метода. Если ваша исходная программа написана на объектно-ориентированном Паскале, то нижняя область окна показывает, является ли метод процедурой или функци- ей. Нажатие клавиши Enter в любом месте окна проверки метода или функций-элементов классов (Inspector) выводит на передний план окно Module (Модуль) и помещает курсор на код, который реализует проверяемый метод. Как и в стандартном окне проверки, нажатие клавиши Esc зак- TDeb 3.0 #2-3 = 36 = рывает текущее окно Inspector (Проверка), а нажатие клавиш Alt-F3 закрывает их все. Локальное меню окна Object Type/Class Inspector ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Нажатие клавиш Alt-F10 выводит локальное меню любой области. Если разрешено использование сокращений с клавишей Ctrl (с по- мощью утилиты TDINST), то вы можете получить элемент локального меню путем нажатия клавиши Ctrl и первой буквы элемента. Верхняя область (область полей данных объектов) содержит следующие эле- менты меню: ЪДДДДДДДДДДДДДДДДДДДДДДї Проверка і Inspect і Иерархия і Hierarchy і Вывод наследования і Show inherited Yes і АДДДДДДДДДДДДДДДДДДДДДДЩ Область полей данных объекта (верхняя) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Локальное меню области полей данных объекта содержит следую- щите элементы: Команда Inspect (Проверка) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Если подсвеченное поле является объектным типом или указате- лем на него, то для подсвеченного поля открывается новое окно проверки типов объектов/классов (Object Type/Class Inspector). Команда Hierarchy (Иерархия) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Открывает окно иерархии объектов (Hierarchy) для проверяемо- го объектного типа или класса. Это окно описано выше. Show Inherited (Вывод наследования) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Yes (Да) является значением по умолчанию этого переключате- ля. Когда он установлен в значение Yes, показываются все поля данных и методы (функции), независимо от того, определены ли они внутри данного (проверяемого) типа объекта (класса), или они унаследованы от родительского (порождающего) типа. Когда переклю- чатель установлен в значение No (Нет), на экран выводятся только определенные внутри проверяемого типа поля и методы (функции-эле- менты). TDeb 3.0 #2-3 = 37 = Область методов объекта (нижняя) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Перечислим элементы локального меню нижней области (области методов объектов): ЪДДДДДДДДДДДДДДДДДДДДДДї Проверка і Inspect і Иерархия і Hierarchy і Вывод наследования і Show inherited Yes і АДДДДДДДДДДДДДДДДДДДДДДЩ Команда Inspect (Проверка) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для подсвеченного метода открывается окно проверки функ- ции/метода (Inspector). Если вы нажмете клавиши Ctrl-I, а курсор будет при этом находиться выше адреса, показанного в окне провер- ки метода/функции, то на переднем плане появится окно Module (Мо- дуль), а курсор будет находиться на коде, реализующем проверяемый метод (функцию). Команда Hierarchy (Иерархия) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Открывает окно иерархии объектов (Hierarchy) для проверяемо- го объекта или класса. Это окно описано выше. Show Inherit (Вывод наследования) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Yes (Да) является состоянием по умолчанию для этого переклю- чателя. Когда он установлен в значение Yes, то показываются все методы или функции-элементы, независимо от того, определены ли они в проверяемом объекте (классе), или они унаследованы от роди- тельского типа объекта (класса). Если этот переключатель установ- лен в значение No (Нет), то показываются только методы, опреде- ленные в проверяемом типе объекта (класса). TDeb 3.0 #2-3 = 38 = Окно Object/Class Instance Inspector ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окна Object/Class Instance Inspector (Проверка экземпляра объектов/классов) обеспечивают информацию о типах объектов, но ничего не говорит о данных, содержащихся в отдельном экземпляре объекта или класса в данный момент выполнения программы. Турбо отладчик предоставляет расширенную форму знакомых уже окон про- верки записей специально для проверки экземпляров объектов или классов. Откройте это окно путем установки курсора на экземпляр объ- екта в окне Module (Модуль), затем нажмите клавиши Ctrl-I. ЙН[*]ННInspecting twННННННННННННН3НН[ ][ ]» є@75C6:01E8 ^ єScreen::MaxX 500 (Ox1F4) ° єScreen::MaxY 512 (Ox200) v є<І°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°>є єScreen::Convert @0000:0000 є єScreen::VertVtoA @0000:0000 є єScreen::VertAtoV @0000:0000 є єДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДє єclass TextWindow є ИНННННННННННННННННННННННННННННННННННННННННЅ Рис. 10.3 Окно Object/Class Instance Inspector Большинство окон Турбо отладчика, предназначенных для про- верки данных записи, имеют две части (области). В верхней области выводятся имена полей записи и их текущие значения, а в нижней - тип поля, подсвеченного в верхней области. Окно проверки экземп- ляра объекта/класса (Object/Class Instance Inspector) предостав- ляет обе эти области, а также третью область между ними. Эта но- вая область содержит методы экземпляра объекта или функции-эле- менты с адресами кода для каждого метода (функции). (Адрес кода учитывается полиморфическими объектами и в таблице виртуальных методов.) Примечание: Полное описание таблицы виртуальных методов можно найти в руководствах по Турбо Паскалю. TDeb 3.0 #2-3 = 39 = Локальное меню окна Object/Class Instance Inspector ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Каждая из двух верхних областей окна проверки экземпляром объектов/классов (Object/Class Instance Inspector) имеет свое собственное локальное меню, которое выводится на экран путем на- жатия клавиш Alt-F10. Здесь вы также можете использовать сокраще- ния с клавишей Ctrl для получения отдельных элементов меню, если их использование разрешено с помощью утилиты TDINST. ЪДДДДДДДДДДДДДДДДДДДДДї Диапазон і Range... і Изменение і Change... і Методы і Methods Yes і Вывод наследования і Show inherited Yes і ГДДДДДДДДДДДДДДДДДДДДДґ Проверка і Inspect і Спуск і Descend і Новое выражение і New expression... і Приведение типа і Type cast і Иерархия і Hierarchy і АДДДДДДДДДДДДДДДДДДДДДЩ Как и в окне проверки записи (Inspector), нижняя область служит только для вывода типа подсвеченного поля и не имеет ло- кального меню. Верхняя область, которая содержит поля данных объекта, имеет следующие локальные команды: Команда Range... (Диапазон) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Эта команда не изменилась при переходе от более ранних вер- сий. Она позволяет выводить на экран границы элементов массива. Если элемент не является массивом или указателем, то эта команда недоступна. Команда Change... (Изменение) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Путем выбора этой команды вы можете загрузить новые значения в подсвеченное поле данных. Эта команда также не претерпела изме- нений по сравнению с более ранними версиями Турбо отладчика. Команда Methods (Методы) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Эта команда является переключателем между состояниями Yes/No (Да/Нет) и с состоянием Yes (Да) по умолчанию. Если переключатель установлен в значение Yes, то методы выводятся в средней области. В состоянии No (Нет) средняя область отсутствует. Этот переключа- тель запоминается следующим окном Inspector (Проверка), которое TDeb 3.0 #2-3 = 40 = будет открыто. Команда Show Inherited (Вывод наследования) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Это элемент, который также переключается между состояниями Yes и No. В состоянии Yes (Да) выводятся все поля данных и мето- ды, независимо от того, определены ли они в проверяемом объекте, или они унаследованы от родительского типа. В состоянии No (Нет) выводятся только те поля и методы, которые определены в проверяе- мом объектном типе. Команда Inspect (Проверка) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Как и в предыдущих версиях Турбо отладчика, выбор этой ко- манды открывает окно проверки данных (Inspector) для подсвеченно- го поля. Нажатие клавиши Enter над подсвеченным полем ведет к то- му же результату. Команда Descend (Спуск) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Эта команда не изменилась по отношению к более ранним верси- ям Турбо отладчика. Подсвеченный элемент занимает место элемента в текущем окне Inspector. Не открывается никаких новых окон Inspector. Однако, вы не можете вернуться к предыдущему проверяе- мому полю, как могли бы сделать это, если бы использовали пара- метры Inspect. Примечание: Используйте команду Descend (Спуск) при вы- полнении трассировки сложных структур данных и когда вы не собираетесь открывать отдельное окно проверки (Inspector) для каждого проверяемого элемента. Команда New Expression... (Новое выражение) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Данная команда не изменена по сравнению с предыдущими версия- ми Турбо отладчика. Эта команда подсказывает вам о необходимости ввести новый элемент данных или выражение для проверки. Новый элемент замещает текущий в окне, а новое окно не открывается. Команда Type Cast... (Приведение типа) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Type Cast (Приведение типа) позволяет вам задать для проверяемого элемента другой тип данных. Ее полезно использовать, если окно Inspector содержит идентификатор, для которого нет ин- формации о типе, а также для явного задания типа указателей. Команда Hierarchy (Иерархия) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД TDeb 3.0 #2-3 = 41 = При выборе данной команды открывается окно иерархии объекта (Hierarchy). Полное описание этого окна приведено выше. Средняя и нижняя область ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В среднем окне выводятся методы объекта. Единственным отли- чием между локальным меню области методов и локальным меню облас- ти полей данных (верхняя область) является отсутствие команды Change (Изменение). В отличие от полей данных, методы и функ- ции-элементы нельзя изменять в процессе выполнения, поэтому нет нужды в такой команде. В нижней области выводится тип элемента, подсвеченного в верхних двух областях. TDeb 3.0 #2-3 = 42 = Глава 11. Отладка на уровне Ассемблера ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Данная глава предназначена для программистов, которые знако- мы с программированием на Ассемблере для процессоров серии 80х86. Примечание: Вам не обязательно использовать при отладке программы возможности, которые здесь описаны, но при возник- новении определенных проблем их можно быстрее и проще устра- нить, если использовать описанные в данной главе методы. Мы поясним, в каких случаях желательно использовать отладку на уровне Ассемблера. Затем мы опишем окно центрального процессо- ра (CPU) со встроенным дисассемблером и Ассемблером. Вы узнаете, как можно с помощью данного окна проверять и модифицировать байты данных непосредственно в шестнадцатиричном виде, как анализиро- вать стек вызова функций, как проверять и модифицировать регистры центрального процессора (ЦП) и его флаги. Когда недостаточно отладки на уровне исходного кода ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В большинстве случаев при отладке программы вы ссылаетесь на код и данные программы на уровне исходного кода, обращаясь к име- нам идентификаторов точно так, как они набраны в исходном коде, и "проходите" программу, выполняя участки исходного кода. Однако иногда лучше рассмотреть проблему "изнутри", анализи- руя те инструкции. которые генерирует компилятор, содержимое ре- гистров ЦП и его стека. Чтобы сделать это, вы должны быть знакомы как с процессором серии 80х86, так и с компилятором, который превращает ваш код в машинные инструкции. Поскольку функциониро- ванию ЦП посвящено много превосходных книг, мы не собираемся рассказывать здесь об этом подробно. Мы только кратко расскажем о том, как компилятор превращает исходный код в машинные инструк- ции, рассмотрев инструкции, генерируемые каждой строкой исходного кода. Язык Си, или Паскаль, например, позволяет вам записывать строки исходного кода, которые выполняют несколько действий сра- зу. Поскольку отладчик позволяет выполнять программу по одной строке исходного кода, а не по одному выражению языка Си (Паска- ля), вам иногда будет желательно знать результат выполнения части строки исходного кода. Выполняя всю программу по одной машинной инструкции, вы сможете проверить промужеточные результаты (хотя потребуются некоторые усилия, чтобы понять, как компилятор транс- лирует исходные операторы в машинный код). TDeb 3.0 #2-3 = 43 = Окно CPU ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В окне CPU (ЦП) показано все состояние центрального процес- сора. С его помощью вы можете проверять и изменять биты и байты, составляющие код и данные программы. В окне Code (Код) для вре- менной коррекции своей программы вы можете использовать встроен- ный Ассемблер. При этом инструкции вводятся точно также, как при наборе исходных операторов Ассемблера. Можно также получить дос- туп к соответствующим данным любой структуры данных, выводя и из- меняя их в различных форматах. Й[*]НCPU 80286НННННННННННННННННННННННННННННННН3ННН[ ][ ]» єTPDEMO.120: Inc(NumLines); ^ ax 0004 іc=0є є cs:04C4:4F36063000 inc word ptr [TPDEMOІ bx 3EEE іz=0є єTPDEMO.121 i := 1; ± cx 0000 іs=0є є cs:04C8 C:43FE0100 word ptr [bp+02].000± dx 5920 іo=0є єTPDEMO.122: while i <= Length(S) do ± si 3CEC іp=0є є cs:04C0 C47ED4 les di,[bp+04] ± bp 3EF4 іa=0є є cs:0400 288A05 mov al,es:[di] ± sp 3EF4 іi=1є є cs:0403 3D84 xor ah,ah ± ds 5920 іd=0є є cs:0405 3B48FE cmp ax,[bp+02] ± es 5920 і є є cs:0408 7D03 jnl TPDEMO.125 (04DD) ± ss 595A і є є cs:040A 898A00 jmp TPDEMO.148 ± cs 548A і є єTPDEMO.125 while (i <= Length(S)) and notv ip 04C8 і є є<І±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>іДДДДДДДДДДДДДє є ds:0000 00 00 00 00 00 00 00 00 і є є ds:0008 5A 5D 5A 5D 5A 5D 00 00 і ss:3EF2 548Aє є ds:0010 00 00 00 00 00 00 5A 5D і ss:3EF0>04C1є є ds:0018 00 00 5A 5D 00 00 00 90 і ss:3EEE 0246є ИНННННННННННННННННННННННННННННННННННННННННННННННННННННННЅ Рис. 11.1 Окно CPU Окно CPU (ЦП) можно создать, выбрав команду основного меню ViewіCPU (ОбзоріЦентральный процессор). В зависимости от того, что вы просматриваете в текущем окне, окно CPU будет позициониро- вано на соответствующие код, данные или стек. Это предоставляет удобный способ просматривать код, данные или стек (соответствую- щие текущему положению курсора) "на нижнем уровне". В следующей таблице показано, где будет позиционирован курсор при выборе ко- манды CPU: ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Текущее окно Область окна CPU Позиционируется на... ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно Stack (Стек) Stack (Стек) Текущие SS:SP Окно Module (Модуль) Code (Код) Текущие SS:SP Окно Variable (Переменная) Данные/Код Адрес элемента Окно Watches (Просмотр) Данные/Код Адрес элемента Окно Inspector (Проверка) Данные/кодж Адрес элемента Точка останова (не Код Адроес точки глобальная) останова TDeb 3.0 #2-3 = 44 = ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Если TDW вновь получает управление от вашей прикладной прог- раммы, а текущим выполняемым кодом является код Windows или DLL, то TDW автомачески переводит вас в окно CPU. Строка в верхней части окна CPU (ЦП) показывает тип процес- сора (8086, 80186, 80286 или 80386). Окно CPU имеет пять облас- тей (или 6 в TDW). Чтобы переходить из одной области в другую, можно использовать клавиши Tab или Shift-Tab. В верхней левой об- ласти (области кода) выводится дисассемблированный код программы, чередующийся со строками исходного текста. Во второй области (об- ласти регистров) показано содержимое регистров ЦП. Правая область представляет собой область флагов, где выводится состояние восьми флагов ЦП. В нижней левой области (области данных) в непосредс- твенном шестнадцатиричном виде выводится любая выбранная вами об- ласть памяти. В нижней правой области (области стека) показано содержимое стека. Если вы работаете с TDW, то в окне CPU имеется дополнитель- ная область - область селекторов. Эта область, которая расположе- на слева от области кода и области данных, показывает все селек- торы Windows и показывает содержимое каждого из них. Как и во всех других окнах, нажатие клавиш Alt-F10 приводит к выводу локального меню области кода. Если разрешено использова- ние сокращений с клавишей Ctrl, то нажатие клавиши Ctrl с первой буквой нужной команды может использоваться для непосредственного доступа к команде. В области кода, данных и стека для смещения начального адре- са вывода на 1 байт вверх или вниз можно использовать клавишу Ctrl со стрелками. Если вы хотите просто слегка сместить изобра- жение, это легче, чем использовать команду Goto (Переход). TDeb 3.0 #2-3 = 45 = Область кода ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В этой области по выбранному вами адресу выводятся дисас- семблированные инструкции. Примечание: Стрелка (>) в области кода показывает теку- щий адрес программы (CS:IP). В области стека стрелка показы- вает текущий указатель стека (SS:SP). В левой части каждой дисассемблированной строки выводится адрес инструкции. Адрес выводится либо в виде шестнадцатиричного значения сегмента и смещения, либо со значением сегмента, заме- ненным именем регистра CS (если значение сегмента совпадает с те- кущим значение регистра CS). Эта область имеет ширину (которая может переключаться или настраиваться), достаточную для вывода всех образующих инструкцию байт. Дисассемблированная инструкция выводится справа. Если в подсвеченной инструкции области кода имеется ссылка на память, то адрес памяти и его текущее содержимое выводятся в верхней строке окна CPU. Это позволяет вам увидеть как операнд инструкции, который указывает на память, так и значение, которое будет записано или считано. Дисассемблер ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В области кода автоматически дисассемблируются и выводятся на экран инструкции вашей программы. Если адрес соответствует глобальному, статическому идентификатору или номеру строки, то (если режим вывода Mixed установлен в значение Yes) перед дисас- семблированной инструкцией выводится строка. Кроме того, если имеется строка исходного кода, соответствующая адресу идентифика- тора, то она выводится после идентификатора. Глобальные идентификаторы выводятся просто в виде имени идентификатора. Статические идентификаторы выводятся в виде имени модуля, за которым следует символ # или точка (.) и имя статичес- кого идентификатора. Номера строк выводятся в виде имени модуля, за которым следует разделяющий символ # или точка (.) и десятич- ный номер строки. При выводе непосредственного операнда вы можете определить его размер по числу цифр. Непосредственное байтовое значение сос- тоит из 2 цифр, а непосредственное значение размером в слово - из 4 цифр. Турбо отладчик может распознавать наличие числового сопро- цессора 8087/80287/80387 и дисассемблировать соответствующие инс- трукции с плавающей точкой. Мнемоника инструкции RETF показывает, что это инструкция TDeb 3.0 #2-3 = 46 = возврата дальнего типа. Обычная мнемоника RET свидетельствует о ближнем возврате. Там, где это возможно, инструкции JMP и CALL выводятся в символическом виде. Если CS:IP указывают на инструкцию JMP или инструкцию условного перехода, то стрелка (стрелка вверх или вниз), показывающая направление перехода, будет выводиться только в том случае, если выполнение инструкции приведет к переходу. Кроме того, адреса памяти, использующиеся в инструкциях MOV, ADD и др., выводятся в виде символических адресов. TDeb 3.0 #2-3 = 47 = Локальное меню области кода ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Если вы не перешли в область кода, используйте для этого клавиши Tab или Shift-Tab. Затем для вывода локального меню наж- мите клавиши Alt-F10. ЪДДДДДДДДДДДДДДї і Goto... і Переход і Origin і Начало і Follow і Следующая і Caller і Вызывающая і Previous і Предыдущая і Search... і Поиск і View source і Просмотр исходного кода і Mixed Yes і Смешанный ГДДДДДДДДДДДДДДґ і New cs:ip і Новый CS:IP і Assemble... і Ассемблер і IіO > і Ввод-вывод АДДДДДДДДДДДДДДЩ Команда Goto... ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД После выбора команды Goto (Переход) вам выводится подсказка для ввода нового адреса, на который вы хотите перейти. Вы можете ввести адрес, выходящий за пределы программы, что позволяет про- верить базовую систему ввода-вывода (BIOS), внутренние области DOS и резидентные утилиты. Полное описание ввода адресов содер- жится в Главе 9. Команда Previous (Предыдущий) восстанавливает область кода в то состояние (позицию), которое она имела до выполнения команды Goto. Команда Origin ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Origin (Начало) позиционирует вас на текущий адрес программы в соответствии со значениями регистров CS:IP. Команда Previous (Предыдущий) восстанавливает область кода в то состояние (позицию), которое она имела до выполнения команды Origin. Команда Follow ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Follow (Следующий) позиционирует вас по целевому ад- ресу подсвеченной в данный момент инструкции. Область кода пози- ционируется заново, чтобы вывести код по адресу, указанному в подсвеченной в данный момент инструкции, по которому будет переда- TDeb 3.0 #2-3 = 48 = но управление. Для условных переходов адрес показывается в случае выполнения перехода. Эту команду можно использовать с инструкциями CALL, JMP, ин- струкциями условных переходов (JZ, JNE, LOOP, JCXZ и т.д.) и инс- трукциями INT. Команда Previous (Предыдущий) восстанавливает область кода в то состояние (позицию), которое она имела до выполнения команды Follow. Команда Caller ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Caller (Вызывающая программа) позиционирует вас на инструкцию, по которой была вызвана текущая подпрограмма или пре- рывание. Данная команда будет работать не всегда. Если процедура об- работки прерывания или подпрограмма занесла в стек элементы дан- ных, иногда Турбо отладчик не может определить, откуда был выпол- нен вызов. Команда Previous (Предыдущий) восстанавливает область кода в то состояние (позицию), которое она имела до выполнения команды Caller. Команда Previous ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Previous (Предыдущий) восстанавливает позицию облас- ти кода в соответствии с адресом, который был текущим перед пос- ледней командой, явно изменившей его значение. Использование кла- виш перемещения (стрелок) или PgUp и PgDn не приводит к запоминанию позиции. При использовании команды Previous позиция окна кода запоми- нается, поэтому повторное использование этой команды приводит к переключению между двумя адресами (туда и обратно). Команда Search... ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Search (Поиск) позволяет вам вводить инструкцию или список байт, которые вы хотите найти. Вводите инструкцию точно также, как это делается в команде Assemble (Ассемблирование). Будьте внимательны при поиске инструкций. Следует выполнять поиск только тех инструкций, которые не изменяют байт, в которые они ассемблируются, в зависимости от того, где в памяти они ас- семблируются. Например, поиск следующих инструкций проблемы не TDeb 3.0 #2-3 = 49 = представляет: PUSH DX POP [DI+4] ADD AX,100 а попытка поиска следующих инструкций может привести к непредска- зуемым результатам: JE 123 CALL MYFUNC LOOP $-10 Вместо инструкции можно вводить также список байт. Более подробно об этом рассказывается в Главе 9. Команда View Source ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда View Source (Просмотр исходного кода) для вывода ис- ходного кода, соответствующего текущей дисассемблированной инс- трукции открывает окно Module (Модуль). Если соответствующего ис- ходного кода нет (например, вы находитесь в коде Windows, или от- сутствует отладочная информация), вы просто остаетесь в области кода. Команда Mixed ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Локальная команда Mixed (Смешанный) позволяет выбрать один из трех способов вывода на экран дисассемблированных инструкций и исходного кода: No (Нет) Исходный код не выводится, выводятся только ди- сассемблированные инструкции. Yes (Да) Перед первой дисассемблированной инструкцией, со- ответствующей данной строке, выводится строка ис- ходного кода. Область устанавливается в данный режим, если исходный модуль написан на языке вы- сокого уровня. Both (Оба) Для тех строк, которым соответствует исходный код, дисассемблированные строки заменяются стро- ками исходного текста. В противном случае выво- дятся дисассемблированные инструкции. Используйте этот режим, когда вы отлаживаете модуль на Ас- семблере и хотите видеть строку исходного текста, а не соответствующую дисассемблированную инструк- цию. Область устанавливается в данный режим выво- да, если текущим модулем является исходный модуль Ассемблера. TDeb 3.0 #2-3 = 50 = Команда New CS:IP ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда New CS:IP (Новое значение регистров CS:IP) устанав- ливает значение счетчика адреса программы (значение регистров CS: IP) в соответствии с текущим (подсвеченным) адресом. При повтор- ном запуске вашей программы выполнение начнется с этого адреса. Это полезно использовать, когда вы хотите пропустить какие-либо участки кода, не выполняя их. Пользоваться данной командой нужно очень аккуратно. Если вы изменяете значение регистров CS:IP в соответствии с адресом, где стек имеет состояние, отличное от текущего значения CS:IP, то это почти наверняка приведет к аварийному завершению программы. Не пользуйтесь этой командой, чтобы установить регистры CS:IP в зна- чение адреса, лежащего за пределами программы. Команда Assemble... ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Assemble (Ассемблирование) ассемблирует инструкцию, заменяя текущую (подсвеченную) инструкцию. Инструкция, которую требуется ассемблировать, вводится в ответ на подсказку. Более детально это описывается далее в данной главе в разделе "Ассемб- лер". Данную команду можно вызвать, если просто начать набирать оператор, который вы хотите ассемблировать. Когда вы делаете это, то выводится окно подсказки (так же, как при использовании коман- ды Assemble). Команда I/O ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда I/O (Ввод-вывод) считывает или записывает значение в пространство адресов ввода-вывода ЦП и позволяет вам проверить содержимое регистров ввода-вывода и записать в них значения. При этом выводится меню, показанное ниже: ЪДДДДДДДДДДДДї і In byte і Ввести байт і Out byte і Вывести байт і Read byte і Прочитать байт і Write byte і Записать байт АДДДДДДДДДДДДЩ Команда In Byte ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда In Byte (Ввести байт) считывает байт из адреса ввода -вывода. Вам будет выведена подсказка для ввода адреса ввода-вы- вода, значение которого вы хотите проверить. Для считывания из адреса ввода-вывода значения размером в слово используйте команду TDeb 3.0 #2-3 = 51 = Read word (Считать слово). Команда Out Byte ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Out Byte (Вывести байт) записывает байт по заданному адресу ввода-вывода. Вам будет выведена подсказка для ввода адре- са ввода-вывода и значение, которое вы хотите записать. Для запи- си по адресу ввода-вывода значения размером в слово используйте команду Read word (Считать слово). Команда Read Word ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Read Word (Считать слово) считывает слово из адреса ввода-вывода. Вам будет выведена подсказка для ввода адреса ввода -вывода, значение которого вы хотите проверить. Для считывания из адреса ввода-вывода значения размером в байт используйте команду Read byte (Считать байт). Команда Write Word ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Write Word (Записать слово) записывает слово по ад- ресу ввода-вывода. Вам будет выведена подсказка для ввода адреса ввода-вывода и значения, которое вы хотите записать. Для считыва- ния из адреса ввода-вывода значения размером в байт используйте команду Write byte (Считать байт). Обращаться к пространству адресов ввода-вывода, где находят- ся такие контроллеры периферийных устройств, как контроллер дис- ка, платы последовательных портов и видеоадаптеры, можно с по- мощью инструкций Ассемблера IN и OUT. Будьте внимательны при использовании данных команд. В неко- торых портах ввода-вывода считывание из порта рассматривается, как значительное событие, приводящее к тому, что устройство вы- полняет некоторые действия, такие, как переустановка бита состоя- ния или загрузка в порт нового байта. При неограниченном исполь- зовании данных команд вы можете нарушить нормальную работу отлаживаемой программы или устройства. TDeb 3.0 #2-3 = 52 = Область регистров и флагов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В области регистров (верхняя область справа от области кода) выводится содержимое регистров центрального процессора. Верхней правой областью является область флагов, где показа- но содержимое восьми флагов центрального процессора. В области флагов показано значение каждого флага ЦП. Список различных фла- гов и то, как они выводятся в области флагов, показан в следующей таблице: ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДї і Буква в области і Название флага і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДґ і c і Флаг переноса і і z і Флаг нуля і і s і Флаг знака і і o і Флаг переполнения і і p і Флаг четности і і a і Флаг дополнитель- і і і ного переноса і і i і Флаг разрешения і і і прерывания і і d і флаг направления і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДЩ Локальное меню области регистров ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для вывода локального меню области регистров нажмите клавиши Alt-F10. Если разрешено использование сокращений с клавишей Ctrl, то нажатие клавиши Ctrl с первой буквой нужной команды может ис- пользоваться для непосредственного доступа к команде. ЪДДДДДДДДДДДДДДДДДДДї Увеличение і Increment і Уменьшение і Decrement і Обнуление і Zero і Изменение і Change... і 32-разрядные регистры і Register 32-bit Noі АДДДДДДДДДДДДДДДДДДДЩ Команда Increment ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Increment (Увеличение) добавляет одно значение к подсвеченному в данный момент регистру. Это позволяет легко исп- равить небольшие ошибки в значении регистра. Команда Decrement ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Decrement (Уменьшение) вычитает 1 из значения подс- TDeb 3.0 #2-3 = 53 = веченного в данный момент регистра. Команда Zero ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Zero (Ноль) обнуляет содержимое текущего (подсвечен- ного) регистра. Команда Change... ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Change (Изменение) изменяет содержимое текущего (подсвеченного) регистра. Для ввода нового значения вам выводится подсказка. При вводе нового значения можно использовать средство вычисления выражений. Эту команду можно вызвать также, если просто начать набирать новое значение регистра. Когда вы делаете это, выводится окно подсказки. Команда Registers 32-bit ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Registers 32-bit (32-разрядные регистры) позволяет с вывода регистров ЦП, как 16-разрядных значений, на 32-разрядные. При работе на процессора 80386 вы обычно видите 32-разрядные ре- гистры (если только не использована данная команда для переключе- ния на 16-разрядные регистры). 32-разрядные регистры необходимы только в том случае, если вы отлаживаете программу, в которой ис- пользуются возможности 32-разрядной адресации процессора 386. Ес- ли вы отлаживаете обычную программу, в которой используется 16-разрядная адресация, можно выбрать вывод 16-разрядных регист- ров. Локальное меню области флагов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для вывода локального меню области флагов нажмите клавиши Alt-F10. Если разрешено использование сокращений с клавишей Ctrl, то нажатие клавиши Ctrl с первой буквой нужной команды может ис- пользоваться для непосредственного доступа к команде. ЪДДДДДДДДї Переключение і Toggle і АДДДДДДДДЩ TDeb 3.0 #2-3 = 54 = Команда Toggle ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Toggle (Переключение) устанавливает значение флага в 0, если он был равен 1, и в 1, если он был равен 0. Значение 0 означает, что флаг сброшен, а 1 - что он установлен. Для измене- ния (инвертирования) значения текущего (подсвеченного) флага мож- но также нажать клавишу Enter. TDeb 3.0 #2-3 = 55 = Область селектора ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В этой области выводится список селекторов защищенного режи- ма и указывается некоторая информация для каждого из них. Селектор может быть допустимым или нет. Допустимый селектор указывает на ячейку таблицы дескрипторов защищенного режима, со- ответствующего адресу памяти. Если селектор недопустим, то он не используется. Для допустимого селектора в области выводится следующее: - являются ли содержимым данные или код; - загружена ли область памяти, на которую ссылается селектор (присутствует в памяти) или разгружена (выведена на диск); - длина сегмента памяти, на которую ссылается селектор (в байтах). Если селектор ссылается на сегмент данных, то имеется допол- нительная информация по полномочиям доступа (Read/Write - Чтение/ Запись или Read only - только чтение) и направление расширения сегмента в памяти (Up - вверх или Down - вниз). Локальное меню области селектора ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для вывода локального меню в области селектора нажмите кла- виши Alt-F10, или, если разрешено использование сокращений с кла- вишей Ctrl, для доступа к нужной команды используйте клавишу Ctrl с подсвеченной буквой команды. ЪДДДДДДДДДДДДї Селектор і Selector і Проверка і Examine... і АДДДДДДДДДДДДЩ Локальное меню области селектора вы можете использовать для перехода к новому селектору (команда Selector) или просмотра со- держимого селектора, который подсвечен в данный момент в области селектора (команда Examine). Содержимое выводится в области кода или в области данных, в зависимости от его характера. Команда Selector ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Данная команда выводит вам подсказку для ввода селектора, который нужно вывести в области. Для ввода селектора вы можете использовать полный синтаксис выражений. Если вы вводите числовое значение, то TDW подразумевает, что оно десятичное (если вы не используете синтаксис текущего языка для указания того, что зна- TDeb 3.0 #2-3 = 56 = чение является шестнадцатиричным). Например, если текущим языком является язык Си, вы можете ввести шестнадцатиричное значение селектора 7F как Ox7F. Для Паскаля вы могли бы ввести его как 7F. Чтобы перейти к селектору 7F, можно было бы также ввести десятичное значение 127. Другим методом ввода значения селектора является вывод окна CPU и проверка содержимого сегментных регистров. Если регистр со- держит интересующий вас селектор, то вы можете ввести имя регист- ра с предшествующим символом подчеркивания (_). Например, вы мо- жете задать имя сегментного регистра данных, как _DS. Команда Examine ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Examine (Проверка) выводит содержимое области памя- ти, на которую ссылается текущий селектор, и переключается в об- ласть, где выводится содержимое. Если селектор указывает на сег- мент кода, то содержимое выводится в области кода. Если содержимое представляет собой данные, то оно выводится в области данных. TDeb 3.0 #2-3 = 57 = Область данных ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В этой области показано непосредственное содержимое выбран- ной вами области памяти. В левой части каждой строки показан ад- рес данных, выводимых на данной строке. Адрес выводится в виде шестнадцатиричного значения сегмента и смещения или значение сег- мента заменяется именем сегмента DS, если значение сегмента сов- падает с текущим содержимым регистра DS. Далее в области выводится непосредственное содержимое одного или более элементов данных. Формат этой области зависит от режима вывода, выбранного с помощью команды локального меню Display As (Вывести как...). Если вы выбираете один из форматов вывода с плавающей точкой (Copm, Float, Double, Extended), то на каждой строке выводится одно число с плавающей точкой. При байтовом фор- мате на одной строке выводится 8 байт, в формате размером в слово (Word) - 4 слова на строку, а в длинном формате (Long) - два длинных слова на строку. В правой части каждой строки выводятся символы, соответству- ющие показанным байтам. Турбо отладчик выводит все печатаемые значения, соответствующие байтовым эквивалентам, поэтому не удив- ляйтесь, если на экране вы увидите странные символы - просто это символьный эквивалент шестнадцатиричных значений байт данных. Число байт, выводимых на каждой строке бывает различным и зависит от формата, заданного к команде Display As. Если вы используете окно данных для проверки содержимого дисплейной памяти, данных базовой системы ввода-вывода или векто- ров в младших адресах памяти, вы увидите значения, находящиеся там во время выполнения отлаживаемой программы, а действительные значения при работе Турбо отладчика. Они не совпадают с теми зна- чениями, которые находятся в указанных областях памяти в тот мо- мент, когда вы их просматриваете. Турбо отладчик определяет, что вы обращаетесь к областям данных, которые также используются им самим, и извлекает значения этих данных из их копии для программы пользователя. TDeb 3.0 #2-3 = 58 = Локальное меню области данных ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для вывода локального меню области данных нажмите клавиши Alt-F10. Если разрешено использование сокращений с клавишей Ctrl, то нажатие клавиши Ctrl с первой буквой нужной команды может ис- пользоваться для непосредственного доступа к команде. ЪДДДДДДДДДДДДДДДДї і Goto і Переход і Search і Поиск і Next і Следующая і Change і Изменение і Follow >і Следовать і Previous і Предыдущий ГДДДДДДДДДДДДДДДДґ і Display as >і Вывести как... і Block >і Блок АДДДДДДДДДДДДДДДДЩ Команда Goto ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Goto (Переход) позиционирует вас на адрес в данных. Введите новый адрес, на который вы хотите перейти. Вы можете ввести внутренний адрес DOS, адрес, расположенный в резидентных утилитах или вне вашей программы, что позволяет вам проверить данные в базовой системе ввода-вывода. Полное описание ввода ад- ресов содержится в Главе 9. Команда Search ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Search (Поиск) выполняет поиск строки символов, на- чиная с текущего адреса памяти, указанного позицией курсора. Вве- дите список байт для поиска. При достижении конца сегмента поиск не будет автоматически возобновляться с его начала. Подробнее о списках байт рассказывается в Главе 9. Команда Next ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Next (Следующий) выполняет поиск следующего вхожде- ния списка байт, который вы задали ранее в команде Search (По- иск). Команда Change... ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Change (Изменение) позволяет изменять байты по теку- щему месту расположения курсора. Если содержимое выводится в коде ASCII или в байтовом формате, то выводится подсказка для ввода TDeb 3.0 #2-3 = 59 = списка байт. В противном случае запрашивается элемент, соответс- твующий текущему формату вывода. Полное описание списка байт со- держится в Главе 9. Эту команду можно вызвать также, если просто начать набирать новое значение или значения. Когда вы делаете это, выводится окно подсказки (как при использовании команды Change). Команда Follow ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД По данной команде выводится следующее локальное меню: ЪДДДДДДДДДДДДДДДДДДДДДДДДДї Ближний код і Near code і Дальний код і Far code і ГДДДДДДДДДДДДДДДДДДДДДДДДДґ Смещение данных і Offset to data і Сегмент:смещение і Cegment:offset to data і Базовый сегмент і Base segment:0 to data і АДДДДДДДДДДДДДДДДДДДДДДДДДЩ Команда Near Code ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Данная команда интерпретирует слово под курсором в области данных, как смещение в текущем сегменте кода (как это задается регистром CS). Область кода становится текущей областью и позици- онируется на данный адрес. Команда Far Code ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Данная команда интерпретирует двойное слово под курсором в области данных, как адрес дальнего типа (сегмент и смещение). Об- ласть кода становится текущей и позиционируется на данный адрес. Команда Offset to Data ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Данная команда позволяет вам следовать по цепочке указателей размером в слово (ближнего типа, где используется только смеще- ние). Область данных устанавливается в соответствии со смещением, заданным словом в памяти по текущей позиции курсора. Команда Segment:Offset to Data ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Эта команда позволяет вам следовать по цепочке указателей дальнего типа размером в двойное слово (где используется сегмент и смещение). Область данных устанавливается в соответствии со смещением, заданным двойным словом в памяти по текущей позиции курсора. TDeb 3.0 #2-3 = 60 = Команда Base Segment:0 to Data ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Данная команда интерпретирует слово под курсором, как адрес сегмента, и позиционирует область данных на начало сегмента. Команда Previous локального меню области данных ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Previous (Предыдущий) восстанавливает адрес области данных в адрес, который был до последней команды, явно изменившей значение текущего адреса. Использование клавиш стрелок и клавиш PgUp и PgDn не приводит к запоминанию позиции. Турбо отладчик поддерживает стек из пяти последних адресов, поэтому вы можете вернуться назад после многократного (< 5) ис- пользования команд локального меню Follow, или команды Goto. Команда Display As ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Display As (Режим вывода) позволяет выбирать формат вывода в области данных. Вы можете выбирать один из форматов дан- ных, использующихся в языке Си, Паскале или Ассемблере. Эти фор- маты можно выбрать из меню: ЪДДДДДДДДДДї Байт і Byte і Слово і Word і Длинный тип і Long і Сложный тип і Comp і С плавающей точкой і Float і Вещественный і Real і С удвоенной точностью і Double і С расширенной точностью і Extended і АДДДДДДДДДДЩ Команда Byte ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Byte (Байт) устанавливает область данных в режим вы- вода шестнадцатиричных байтовых данных. Это соответствует типу данных char в языке Си и типу byte в Паскале. Команда Word ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Word (Слово) устанавливает область данных в режим вывода шестнадцатиричных слов. Это соответствует типу данных int в языке Си и типу word в Паскале. TDeb 3.0 #2-3 = 61 = Команда Long ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Long (Длинный) устанавливает область данных в режим вывода длинных шестнадцатиричных целых чисел. Это соответствует типу данных long в языке Си и типу longint в Паскале. Команда Comp ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Comp (Cложный) устанавливает область данных в режим вывода 8-байтовых целых чисел. Выводится десятичное значение чис- ла. Это соответствует типу данных comp в Паскале (формат IEEE). Команда Float ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Float (C плавающей точкой) устанавливает область данных в режим вывода 6-байтовых чисел с плавающей точкой. Выво- дится значение числа с плавающей точкой в научном представлении. Это соответствует вещественному типу данных (real) в Паскале. Команда Double ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Double (C двойной точностью) устанавливает область данных в режим вывода 8-байтовых чисел с плавающей точкой. Выво- дится значение числа с плавающей точкой в научном представлении. Это соответствует типу данных с двойной точностью (double) в язы- ке Си. Команда Extended ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Extended (C расширенной точностью) устанавливает об- ласть данных в режим вывода 10-байтовых чисел с плавающей точкой. Выводится значение числа с плавающей точкой в научном представле- нии. Это внутренний формат, используемый в сопроцессоре 80х87. Он соответствует также типу длинных данных с двойной точностью (long double) в языке Си и типу с расширенной точностью (extended) в Паскале. Команда Block ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Block (Блок) позволяет вам работать с блоками памя- ти. Вы можете перемещать, очищать, присваивать значения блокам памяти, а также записывать и считывать блоки памяти из файлов на диске. По данной команде на экран выводится всплывающее меню, по- казанное ниже: = 62 = ЪДДДДДДДДДДДї і Clear... і Очистка і Move... і Перемещение і Set... і Установка і Read... і Чтение і Write... і Запись АДДДДДДДДДДДЩ Команда Clear ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Clear (Очистка) устанавливает непрерывный блок в па- мяти в значение 0. Адрес блока и число байт, которые требуется очистить, запрашиваются в выводимой подсказке. Команда Move ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Move (Перемещение) копирует блок памяти из одного адреса в другой. Адреса исходного и целевого блока, а также число копируемых байт, будут запрашиваться в выводимой подсказке. Команда Set ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Set (Присваивание) присваивает непрерывному блоку в памяти конкретное байтовое значение. Адрес блока, число байт, ко- торым требуется присвоить значение, а также само значение запра- шиваются в выводимой подсказке. Команда Read ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Read (Cчитывание) считывает все содержимое или часть файла в блок памяти. Вам сначала будет выведена подсказка для ввода имени считываемого файла, затем адреса, куда требуется счи- тать информацию, и числа считываемых байт. Команда Write ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Write (Запись) записывает блок памяти в файл. Вам сначала будет выведена подсказка для ввода имени файла, куда тре- буется записать данные, затем блока памяти, который нужно запи- сать, и числа считываемых байт. TDeb 3.0 #2-3 = 63 = Область стека ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В области стека (в нижнем правом углу окна CPU) показано со- держимое стека. Область стека ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В области стека для вывода локального меню нажмите клавиши Alt-F10. Если разрешено использование сокращений с клавишей Ctrl, то нажатие клавиши Ctrl с первой буквой нужной команды может ис- пользоваться для непосредственного доступа к команде данного ло- кального меню. ЪДДДДДДДДДї Переход іGoto... і Начало іOrigin і Следующий іFollow і Предыдущий іPrevious і Изменение іChange...і АДДДДДДДДДЩ Команда Goto... ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Goto (Переход) позиционирует вас на адрес в стеке. Введите новый адрес стека. При желании вы можете ввести адрес, выходящий за пределы стека программы, хотя для проверки любых данных вне программы используется обычно область данных. Полное описание ввода адресов содержится в Главе 9. Команда Previous (Предыдущий) восстанавливает область стека в то состояние (позицию), которое она имела до выполнения команды Goto. Команда Origin ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Origin (Начало) позиционирует вас на слово в стеке, указанное текущим (подсвеченным) словом. Это полезно использовать для обратного отслеживания изменения границ стека при возврате в вызывающую функцию. Команда Previous (Предыдущий) восстанавливает область стека в то состояние (позицию), которое она имела до выполнения команды Origin. Команда Follow ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Follow (Следующий) позиционирует вас на слово в сте- ке, указанное текущим (подсвеченным) словом. Это полезно исполь- TDeb 3.0 #2-3 = 64 = зовать для обратного отслеживания изменения границ стека при возврате в вызывающую функцию. Команда Previous (Предыдущий) восстанавливает область стека в то состояние (позицию), которое она имела до выполнения команды Follow. Команда Previous ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Previous (Предыдущий) восстанавливает позицию облас- ти стека в соответствии с адресом перед последней командой, кото- рая явно изменила выводимый адрес. Использование клавиш перемеще- ния (стрелок) или PgUp и PgDn не приводит к запоминанию позиции. При использовании команды Previous позиция окна стека запо- минается, поэтому повторное использование этой команды приводит к переключению между двумя адресами (туда и обратно). Команда Change... ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Change (Изменение) позволяет вам ввести новое значе- ние для текущего (подсвеченного) слова в стеке. Данную команду можно вызвать также, если просто начать вводить новое значение для подсвеченной записи в стеке. Когда вы это делаете, выводится окно подсказки (как и при использовании команды Change). TDeb 3.0 #2-3 = 65 = Ассемблер ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик позволяет вам ассемблировать инструкции про- цессоров 8086, 80186 и 80286, а также арифметических сопроцессо- ров 8087, 80287 и 80387. Когда для модификации программы используется встроенный (внутренний) ассемблер Турбо отладчика, внесенные в нее изменения не являются постоянными. Если вы перезагрузите свою программу с помощью команд RunіProgram Reset (ВыполнениеіСброс программы) или загрузите другую программу с помощью команды FileіOpen (ФайліОтк- рыть), то все сделанные вами изменения будут потеряны. Обычно Ассемблер используется для проверки правильности предположений о коррекции программы. После того, как вы убеди- тесь, что при изменениях программа работает правильно, нужно из- менить исходный код и перекомпилировать и перекомпоновать прог- рамму. В следующих разделах описываются различия между встроенным Ассемблером и синтаксисом, воспринимаемым Турбо Ассемблером. Переопределения размера адреса операнда ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для вызовов (CALL) инструкции перехода (JMP) и инструкций условного перехода (JNE, JL, и т.д.) Ассемблер автоматически ге- нерирует наименьшую инструкцию, с помощью которой можно достичь целевого адреса. Перед целевым адресом, чтобы ассемблировать инс- трукцию с заданным размером, можно использовать переопределения NEAR (ближний) и FAR (дальний). Например: CALL FAR XYZ JMP NEAR A1 Память и непосредственные операнды ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Когда вы используете в своей программе идентификатор в ка- честве операнда инструкции, нужно указать встроенному Ассемблеру, имеете ли вы в виду содержимое идентификатора или его адрес. Если вы используете просто имя идентификатора, то Ассемблер интерпре- тирует его, как адрес (как если бы перед ним использовалась опе- рация Ассемблера OFFSET). Если идентификатор заключается в квад- ратные скобки, то он будет означать ссылку на память. Если в вашей программе содержится определение данных: A DW 4 вы можете ссылаться на содержимое идентификатора A, ассемблируя: с помощью [A]. TDeb 3.0 #2-3 = 66 = Когда вы ассемблируете инструкцию или вычисляете выражение Ассемблера для ссылки на содержимое переменной, используйте само имя переменной или имя переменной, заключенное в квадратные скоб- ки: mov dx,A mov ax,[a] Для ссылки на адрес переменных можно использовать операцию OFFSET: mov ax,offset a Переопределение размера данных в операндах ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В некоторых инструкциях перед операндом нужно задавать раз- мер операнда, для чего используется одно из следующих выражений: BYTE PTR WORD PTR Приведем примеры инструкций, в которых используются такие переопределения: add BYTE PTR[si],10 mov WORD PTR[bp+10],99 Кроме этих переопределений при ассемблировании инструкций арифметических сопроцессором 8087і80287 вы можете использовать следующие переопределения: DWORD PTR QWORD PTR TBYTE PTR Вот примеры таких переопределений: fild QWORD PTR[bx] stp TBYTE PTR[bp+4] TDeb 3.0 #2-3 = 67 = Строковые инструкции ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД При ассемблировании строковой инструкции в самой мнемонике инструкции нужно указать размер (байт или слово), в противном случае Ассемблер не воспримет такую мнемонику. Например, нужно использовать мнемонику STOSW, а не STOS WORD PTR[DI]. Окно Dump ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В окне Dupm (Дамп) выводится в непосредственном виде дамп любой области памяти. Оно работает так же, как область данных ок- на CPU (ЦП). ЙН[*]ННDumpНННННННННННННННННННН3ННННН[ ][ ]» є ds:0000 CD 20 00 A0 00 9A F0 FE = & U** ^ є ds:0008 1B 02 B2 01 22 31 7C 01 <.^%і.` І є ds:0010 22 31 88 02 52 2B E2 1D vX4-# ± є ds:0018 01 01 01 00 03 FF FF FF v И<І±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>Ѕ Рис. 11.2 Окно Dump Описание содержимого и локального меню для данного окна со- держится ранее в разделе "Локальное меню области данных". Обычно это окно приходится использовать при отладке програм- мы на Ассемблере на уровне исходного кода, когда вы хотите прос- мотреть (на нижнем уровне), как выглядят некоторые области дан- ных. Для создания окна Dump (Дамп) можно использовать команду ViewіDump (ОбзоріДамп). Вы можете также использовать данное окно, находясь в окне Inspector (Проверка), когда нужно в непосредственном виде увидеть байты проверяемого объекта. Для получения окна Dump, позициониро- ванного на данные в окне Inspector, используйте команду ViewіDump (ОбзоріДамп). TDeb 3.0 #2-3 = 68 = Окно Registers ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В окне Registers (Регистры) выводится содержимое регистров и флагов центрального процессора. оно работает, как сочетание об- ластей регистров и флагов в окне CPU (ЦП). ЙН[*]ННRegsННН3Н[ ][ ]» є ax 0000 і c=0 є є bx 0000 і z=0 є є cx 0000 і s=0 є є dx 0000 і o=0 є є si 0000 і p=0 є є di 0000 і a=0 є є bp 0000 і i=1 є є sp 2FFF і d=0 є є ds 61AF і є є es 61AF і є є ss 668F і є є cs 618F і є є ip 084E і є ИНННННННННННННННННННННЅ Рис. 11.3 Окно Registers Описание содержимого и локальных меню для этого окна можно найти в разделе "Локальное меню области регистров". Используйте данное окно, когда при отладке на уровне исход- ного кода программы на Ассемблере вы хотите просмотреть содержи- мое регистров. Вы можете сократить размер окна Module (Модуль) и поместить рядом с ним окно Registers. Примечание: Вы можете уменьшить размер окна Module и вывести наряду с ним окно Registers (Регистры). TDeb 3.0 #2-3 = 69 = Глава 12. Сопроцессор 80х87 и эмулятор ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Если в вашей программе используются числа с плавающей точ- кой, Турбо отладчик позволяет вам проверять и изменять состояние арифметического сопроцессора или программного эмулятора. Данная глава предназначена для программистов, которые знакомы с работой арифметического сопроцессора 80х87. Для отладки программ, которые работают с числами с плавающей точкой, вам не обязательно исполь- зовать возможности, описанные в данной главе, однако некоторые трудноуловимые ошибки найти будет легче. В данной главе мы обсудим различия между платой сопроцессора 80х87 и программным эмулятором. Мы также опишем окно Numeric Processor (Арифметический сопроцессор) и покажем вам, как можно проверять и модифицировать содержимое регистров с плавающей точ- кой, биты состояния и управления. Примечание: Данная глава предназначена для программис- тов, которые знакомы с операциями сопроцессоров серии 80х87. Сопроцессор 80х87 или эмулятор? ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик автоматически распознает, используется ли в вашей программе плата арифметического сопроцессора, или эмулятор, и работает соответствующим образом. Заметим, что большинство программ используют либо эмулятор, либо сопроцессор, но не оба этих средства в одной программе. Если вы написали специальный код на Ассемблере, использующий оба средства, Турбо отладчик не сможет показать вам состояние платы сопроцессора и будет сообщать только об эмуляторе. Окно Numeric Processor ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно Numeric Processor (Арифметический сопроцессор) можно создать с помощью команды основного меню ViewіNumeric Processor (ОбзоріАрифметический сопроцессор). В строке в верхней части окна выводятся текущий указатель инструкций, указатель данных и код операции для инструкции. Указатель данных и указатель инструкций выводятся в виде 20-разрядных физических адресов. Эти адреса мож- но преобразовать в форму "сегмент:смещение", если использовать первые 4 цифры, как значение сегмента, а последние 4 цифры, как значение смещения. Например, если в верхней части окна выводится IPTR=5A669, это можно рассматривать, как адрес 5a66:9 (если вы хотите прове- рить текущие данные и инструкцию в окне CPU (ЦП)). Это окно со- держит три области: в левой области (области регистров) выводится TDeb 3.0 #2-3 = 70 = содержимое регистров с плавающей точкой, в средней области (об- ласти управления) показываются значения управляющих флагов, а в правой области (области состояния) показаны флаги состояния. Й[*]НEmulator IPTR=000000 OPCODE=000 OPTR=00003Н[ ][ ]» єEmpty ST(0) і im=0 і ie=0 є єEmpty ST(1) і dm=0 і de=0 є єEmpty ST(2) і zm=0 і ze=0 є єEmpty ST(3) і om=0 і oe=0 є єEmpty ST(4) і um=1 і ue=0 є єEmpty ST(5) і pm=1 і pe=0 є єEmpty ST(6) іiem=0 і ir=0 є єEmpty ST(7) і pc=3 і cc=9 є є і rc=0 і st=2 є є і ic=1 і є И<І±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±>ЩНННННННННННННЅ Рис. 12.1 Окно Numeric Processor В верхней части окна (первая строка) выводится информация о последней выполненной операции с плавающей точкой: - Emulator показывает, что арифметический сопроцессор эмули- руется. При наличии арифметического сопроцессора вместо этого индикатора появляется индикатор 8087, 80287 или 80387. - IPTR показывает 20-разрядный физический адрес, из которого была извлечена последняя инструкция с плавающей точкой. - OPCODE показывает тип извлеченной инструкции. OPTR показы- вает 20-разрядный адрес в памяти, на который инструкция ссылается (если он имеется). TDeb 3.0 #2-3 = 71 = Область регистров ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД 80-разрядные регистры с плавающей точкой ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В области регистров показан каждый (от ST(0) до ST(7)) из регистров с плавающей точкой и его состояние (valid/zero/special/ empty - допустимое/нулевое/специальное/пустое). Содержимо выво- дится в виде 80-разрядных чисел с плавающей точкой. Если вы переключили окно Numeric Processor (нажав клавишу F5) или расширили его с помощью команды WindowіSize/Move (Ок- ноіРазмер/Перемещение), вы также увидите непосредственное содер- жимое регистров с плавающей точкой, выведенное в виде шестнадца- тиричных байтовых значений. Локальное меню области регистров ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Чтобы вывести локальное меню области регистров, нажмите кла- виши Alt-F10, или для непосредственного доступа к команде меню используйте клавишу Ctrl вместе с первой буквой имени команды. ЪДДДДДДДДДДДДї і Zero і Обнуление і Empty і Пусто і Change... і Изменение АДДДДДДДДДДДДЩ Команда Zero ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Zero (Обнуление) устанавливает текущий (подсвечен- ный) регистр в значение 0. Команда Empty ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Empty (Пусто) присваивает подсвеченному в данный мо- мент регистру пустое значение. Это специальное состояние, показы- вающее, что регистр не содержит более допустимых данных. Команда Change ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Change (Изменение) загружает в текущий (подсвечен- ный) регистр новое значение. Допускается вводить целое значение или значение с плавающей точкой. Введенное вами значение будет преобразовано во временный 80-битовый вещественный формат, ис- пользуемый арифметическим сопроцессором. Эту команду можно вызвать, если просто начать печатать для TDeb 3.0 #2-3 = 72 = регистра с плавающей точкой новое значение. При этом будет выво- диться окно подсказки (как при использовании команды Change). TDeb 3.0 #2-3 = 73 = Область управления ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Биты управления ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В следующей таблице приведен список различных флагов управ- ления, выводимых в области управления. ЪДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і Название в области і Описание флага і ГДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і im і Маска недопустимой операции і і dm і Маска ненормализованной операции і і zm і Маска деления на нуль і і om і Маска переполнения і і um і Маска потери значимости і і pm і Маска точности і і iem і Маска разрешения прерывания (только і і і для сопроцессора 8087) і і pc і Управление точностью і і rc і Управление округлением і і ic і Контроль бесконечности і АДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Локальное меню области управления ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для перемещения в область управления нажмите клавишу Tab, затем для получения локального меню нажмите клавиши Alt-F10. (Вы можете также использовать клавишу Ctrl вместе с первой буквой ко- манды, что позволяет получить непосредственный доступ к команде.) ЪДДДДДДДДї Переключение і Toggle і АДДДДДДДДЩ Команда Toggle ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Toggle (Переключение) позволяет циклически переклю- чать значение текущего (подсвеченного) управляющего флага. Значе- ния большинства флагов могут быть только установлены или сброшены (принимать значения 1 или 0), поэтому данная команда будет перек- лючать флаг в другое значение. Однако некоторые другие флаги мо- гут принимать больше значений. Для таких флагов данная команда будет увеличивать значение флага, пока не будет получено макси- мальное значение, затем снова установит флаг в значение 0. Состояние управляющих флагов можно также переключать, нажи- мая клавишу Enter. TDeb 3.0 #2-3 = 74 = Область состояния ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Биты состояния ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В следующей таблице приведен список различных флагов состоя- ния, выводимых в области состояния. ЪДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і Название в области і Описание флага і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і ie і Недопустимая операция і і de і Ненормализованный операнд і і ze і Деление на нуль і і oe і Переполнение і і ue і Потеря значимости і і pe і Точность і і ir і Запрос прерывания і і cc і Код состояния і і st і Указатель вершины стека і АДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Локальное меню области состояния ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для перемещения в область состояния нажмите клавишу Tab, за- тем для вывода локального меню нажмите клавиши Alt-F10. (Вы може- те также использовать клавишу Ctrl вместе с первой буквой коман- ды, что позволяет получить непосредственный доступ к нужной команде.) ЪДДДДДДДДї Переключение і Toggle і АДДДДДДДДЩ Команда Toggle ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда Toggle (Переключение) позволяет циклически переклю- чать значение текущего (подсвеченного) флага состояния. Значения большинства флагов могут быть только установлены или сброшены (принимать значения 1 или 0), поэтому данная команда будет перек- лючать флаг в другое значение. Однако некоторые другие флаги мо- гут принимать больше значений. Для таких флагов данная команда будет увеличивать значение флага, пока не будет получено макси- мальное значение, затем снова установит флаг в значение 0. Состояние флагов можно также переключать, нажимая клавишу Enter. TDeb 3.0 #2-3 = 75 = Глава 13. Команды Турбо отладчика ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Теперь, после того, как мы рассказали вам о всех командах Турбо отладчика, перечислим их кратко. Мы перечислим и опишем: - все команды, выполняющиеся при нажатии одной из клавиш (функциональной или другой клавиши); - все команды основного меню и команды локальных меню для каждого типа окна; - клавиши, используемые для разных областей окон при ответе на подсказку, а также при задании нового размера окна и его положения; - клавиши перемещения и изменения размера окон. Оперативные клавиши ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Оперативная клавиша - это клавиша, которая выполняет опреде- ленное действие вне зависимости от вашего положения в среде Турбо отладчика TDW. Список всех оперативных клавиш приведен в Таблице 13.1. Функциональная клавиша и соответствующая команда Таблица 13.1 ЪДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї іКлавиша іКоманда меню іФункция і ГДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ іF1 і іВыводит на экран контекстно-і і і ізависимую справочную информа-і і і іцию. і і і і і іF2 іBreakpointsіToggle іУстанавливает в позиции курсо-і і і(Точки остановаіПе- іра точку останова. і і іреключение) і і і і і і іF3 іViewіModule (Обзорі іВыводит список для выбора мо-і і іМодуль) ідуля. і і і і і іF4 іRunіGo to Cursor іВыполняет программу до позицииі і і(ВыполнениеіПереход ікурсора. і і ік курсору) і і і і і і іF5 іWindowіZoom (Окноі іПереключает текущее окно. і і іПереключение) і і і і і і іF6 іWindowіNext Window іВыполняет переход к следующемуі і і(ОкноіСледующее окно) іокну. і і і і і іF7 іRunіTrace Into іВыполняет одну исходную строкуі і і(ВыполнениеіТрасси- іили инструкцию. і TDeb 3.0 #2-3 = 76 = і іровка вглубь) і і і і і і іF8 іRunіStep Over (Вы- іВыполняет одну исходную строкуі і і(полнениеіШаг) іили инструкцию, пропуская вы-і і і ізовы. і і і і і іF9 іRunіRun (Выполне- іВыполняет программу. і і іниеіВыполнение) і і і і і і іF10 і іВызывает основное меню и пере-і і і іводит вас в него. і і і і і ГДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і іAlt-F1 іHelpіPrevious Topic іВыводит последний экран соі і і(CправкаіПредыдущая ісправочной информацией. і і ітема) і і і і і і іAlt-F2 іBreakpointsіAt іУстанавливает точку остановаі і і(Точка остановаіНа...)іпо заданному адресу. і і і і і іAlt-F3 іWindowіClose (Окноі іЗакрывает текущее окно. і і іЗакрытие) і і і і і і іAlt-F4 іRunіBack Trace (Вы- іВыполняет программу "в обрат-і і інениеіОбратная трас- іном направлении". і і ісировка) і і і і і і іAlt-F5 іWindowіUser Screen іПоказывает экран вывода прог-і і і(ОбзоріЭкран поль- іраммы. і і ізователя) і і і і і і іAlt-F6 іWindowіUndo Close іВновь открывает последнее зак-і і і(ОкноіОтменить за- ірытое окно. і і ікрытие) і і і і і і іAlt-F7 іRunіInstruction trace іВыполняет одну инструкцию. і і і(ВыполнениеіТрасси- і і і іровка инструкции) і і і і і і іAlt-F8 іRunіUntil Return (Вы- іВыполняет программу до возвра-і і іполнениеіДо возврата) іта управления из функции. і і і і і іAlt-F9 іRunіExecute To (Выпол-іВыполняет программу до задан-і і інениеіВыполнение іного адреса. і і ідо...) і і і і і і іAlt-F10 і іВызывает локальное меню окна. і і і і і іAlt-1-9 і іПереводит вас в окно с задан-і і і іным номером (1 - 9). і і і і і іAlt- і іПереводит вас в системное ме-і TDeb 3.0 #2-3 = 77 = і пробел і іню. і і і і і іAlt-B і іПереводит в меню Breakpointsі і і і(Точки останова). і і і і і іAlt-D і іПереводит вас в меню Dataі і і і(Данные). і і і і і іAlt-F і іПереводит вас в меню Fileі і і і(Файл). і і і і і іAlt-H і іПереводит вас в меню Helpі і і і(Cправка). і і і і і іAlt-O і іПереводит вас в меню Optionsі і і і(Параметры). і і і і і іAlt-R і іПереводит вас в меню Run (Вы-і і і іполнение). і і і і і іAlt-V і іПереводит вас в меню Viewі і і і(Обзор). і і і і і іAlt-W і іПереводит вас в меню Windowі і і і(Окно). і і і і і іAlt-X і іВыполняет выход из Турбо от-і і і іладчика и возвращает вас ві і і іDOS. і і і і і іAlt-= іOptionsіMacrosіCreate іОпределяет клавиатурную макро-і і і(ПараметрыіМакроко- ікоманду. і і імандыіСоздание) і і і і і і іAlt-минусіOptionsіMacrosіStop іЗаканчивает запись макрокоман-і і іRecording (Параметрыі іды. і і іМакрокомандыіОстано- і і і івить запись) і і і і і і ГДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ іCtrl-F2 іRunіProgram Reset іОстанавливает сеанс отладки иі і і(ВыполнениеіСброс ісбрасывает состояние программыі і іпрограммы) ідля повторного выполнения. і і і і і іCtrl-F4 іDataіEvaluate (Дан- іВычисляет выражение. і і іныеіВычисление) і і і і і і іCtrl-F5 іWindowіSize/Move іИнициализирует перемещение илиі і і(ОкноіРазмен/Переме- іизменение размера окна. і і іщение) і і і і і і іCtrl-F7 іDataіAdd Watch (Дан- іДобавляет переменную в окноі і іныеіДобавить выражениеіпросмотра (Watch). і TDeb 3.0 #2-3 = 78 = і іпросмотра) і і і і і і іCtrl-F8 іBreakpointsіToggle іПереключает состояние точкиі і і(Точка остановаіПере- ів месте расположения курсора. і і іключение) і і і і і і іCtrl-F9 іRunіRun (Выполнениеі іЗапускает программу на выпол-і і іВыполнение) інение. і і і і і іCtrl-F10 і іВызывает локальное меню окна. і і і і і іCtrl-Д> і іСдвигает начальный адрес в об-і і і іласти кода, данных или стекаі і і іокна CPU (ЦП) на 1 байт вверх.і і і і і іCtrl-<- і іСдвигает начальный адрес в об-і і і іласти кода, данных или стекаі і і іокна CPU (ЦП) на 1 байт вниз. і і і і і іCtrl-A і іПеремещение к предыдущему сло-і і і іву. і і і і і іCtrl-C і і"Прокручивает" вниз один эк-і і і іран. і і і і і іCtrl-D і іПеремещает вправо на одну по-і і і ізицию. і і і і і іCtrl-E і іПеремещает вверх на одну стро-і і і іку. і і і і і іCtrl-F і іПеремещает к следующему слову.і і і і і іCtrl-R і і"Прокручивает" вверх на одині і і іэкран. і і і і і іCtrl-S і іПеремещает влево на одну пози-і і і іцию. і і і і і іCtrl-X і іПеремещает вниз на одну стро-і і і іку. і і і і і ГДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ іShift-F1 іHelpіIndex іПереходит к оглавлению опера-і і і ітивного справочника. і і і і і іShift-Tabі іПереводит курсор в предыдущуюі і і іобласть окна или элемент. і і і і і іShift--> і іПеремещает курсор между облас-і і і ітями. і і і і і іShift-<- і іПеремещает курсор между облас-і TDeb 3.0 #2-3 = 79 = і і ітями в окне в соответствии сі іShift-v і інаправлениями стрелок (областьі і і ів направлении стрелки стано-і іShift-^ і івится текущей областью). і і і і і ГДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ іEsc і іЗакрывает окно проверки (Ins-і і і іpector), выводит вас из меню. і і і і і іIns і іНачинает выборку блока текстаі і і і(подсветку). Используйте кла-і і і івиши управления курсоромі і і і(стрелки). і і і і і іTab іWindowіNext Pane іПеремещает курсор к следующейі і і(ОкноіСледующая іобласти окна или к следующемуі і іобласть) іэлементу диалогового окна. і АДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 80 = Команды, доступные из основного меню ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Основное меню (строку меню) можно вызвать с помощью клавиши F10. После этого вы можете перейти на одно из меню: - переместив курсор на заголовок меню и нажав клавишу Enter; - нажав первую буквы подсвеченного элемента (пункта) меню. Кроме того, можно открыть меню непосредственно (не перемеща- ясь сначала к заголовку меню), нажав клавишу Alt в сочетании с первой буквой имени нужного меню. Меню Ё (системное меню) ЪДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іRepaint Desktop іПовторно выводит весь экран. і і(Изобразить экран) і і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іRestore Standard іВосстанавливает стандартную схему окон.і і(Восстановить стандарт)і і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іAbout (О Турбо отлад- іВыводит информацию о Турбо отладчике. і ічике) і і і і і АДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 81 = Меню File (Файл) ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іOpen (Открытие) і Открывает новую программу для отладки. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іChange Dir (Смена і Выполняет переход на новый диск или в і ікаталога) і новый каталог. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іGet Info (Получение і Выводит на экран информацию о программе.і іинформации) і і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іResident (Резидент- і Приводит к тому, что Турбо отладчик за-і іный) і вершит работу и останется резидентным ві і і памяти. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іSymbol Load (Загруз- і Загружает таблицу идентификаторов, і іка таблицы идентифи- і независимую от файла .EXE. і ікаторов) і і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іTable Relocate (Пе- і Задает значение базового сегмента табли-і іремещение таблицы) і цы идентификаторов. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іQuit (Выход) і Возвращает вас в DOS. і і і і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 82 = Меню Edit (Редактирование) ЪДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іCopy (Копирование) іКопирует элемент в карман (Clipboard). і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іPaste (Вставка) іВставляет элемент из кармана в окно илиі і ів диалоговую подсказку. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іCopy to Log (Копирова- іКопирует подсвеченный элемент или эле- і іние в окно Log) імент в точке расположения курсора в і і іокно Log. і і і і АДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Меню View (Обзор) ЪДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іBreakpoints (Точки іПросмотр точек останова. і іостанова) і і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іStack (Стек) іПросмотр стека вызовов функций. і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іLog (Регистрация) іПросмотр журнала регистрации событий и і і іданных. і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іWatches (Выражения іПросмотр наблюдаемых переменных. і іпросмотра) і і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іVariables (Перемен- іПросмотр глобальных и локальных перемен- і іные) іных. і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іModule (Модуль) іПросмотр исходного модуля программы. і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іFile (Файл) іПросмотр содержимого файла на диске в і і ікоде ASCII или в шестнадцатиричном виде. і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ TDeb 3.0 #2-3 = 83 = і і і іCPU (ЦП) іПросмотр инструкций, данных и стека і і іцентрального процессора. і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDump (Дамп) іПросмотр дампа данных в непосредственном і і івиде. і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іRegisters (Регистры)іПросмотр регистров и флагов процессора. і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іNumeric Processor іПросмотр сопроцессора или эмулятора. і і(Арифметический і і ісопроцессор) і і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іExecution History іВыводит код Ассемблера, сохраненный для і і(Протокол выполне- іобратной трассировки или повторного і іния) івыполнения нажатий клавиш. і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іHierarchy (Иерархия)іВыводит список типов объектов или классов і і іи дерево иерархии. і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іWindows messages іВыводит список сообщений Windows для і і(Cообщения Windows) іодного или более окон в вашей прикладной і і іпрограмме. і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іClipboard (Карман) іВыводит на экран окно Clipboard, в кото- і і іров вы можете видеть элементы, скопиро- і і іванные в буфер вырезанного изображения і і і(карман). і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іAnother (Другой...) і і і і і і Module іСоздает другое окно Module (Модуль). і і Dump іСоздает другое окно Dump (Дамп). і і File іСоздает другое окно File (Файл). і і і і АДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 84 = Меню Run (Выполнение) ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іRun (Выполнение) іЗапускает программу на выполнениеі і і(без остановки). і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іGo To Cursor (Переход к іВыполняет программу до текущего і ікурсору) іместа расположения курсора. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іTrace Into (Трассировка іВыполняет одну строку исходного і івглубь) ікода или инструкцию. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іStep Over (Шаг с пропуском) іВыполняет трассировку с пропускомі і ітрассировки вызовов подпрограмм. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іExecute To (Выполнение до...)іВыполняет программу до заданного і і іадреса. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іUntil Return (До возврата іВыполняет программу до возврата і іуправления) іфункцией. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іAnimate (Автоматизировать) іНепрерывно выполняет программу поі і ішагам. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іBack Trace (Обратная трас- іИзменяет порядок выполнения прог-і ісировка) іраммы на обратный (по одной стро-і і іке исходного кода или инструк-і і іции). і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іInstruction Trace (Трасси- іВыполняет одну инструкцию. і іровка инструкций) і і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іArguments (Аргументы) іВыполняет одну инструкцию. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ TDeb 3.0 #2-3 = 85 = і і і іProgram Reset (Сброс програм-іВыполняет перезагрузку текущей і імы) іпрограммы. і і і і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 86 = Меню Breakpoints (Точки останова) ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іToggle (Переключение) і Переключает состояние точки і і і останова в месте расположения і і і курсора. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іAt (На...) і Устанавливает по заданному адресуі і і точку останова. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іChanged Memory Global і Устанавливает глобальную точку і і(Изменение памяти (глоб.)) і для области памяти. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іExpression True Global і Устанавливает глобальную точку і і(Выражение истинно (глоб.)) і для выражения. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDelete All (Удалить все) і Удаляет все точки останова. і і і і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Меню Data (Данные) ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іInspect (Проверка) і Проверяет объект данных. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іEvaluate/Modify (Вычисление/ і Вычисляет выражение. і іМодификация) і і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іAdd Watch (Просмотр) і Добавляет переменную в окно і і і просмотра. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іFunction Return (Возврат і Проверяет значение, возвращаемоеі іфункции) і текущей функцией. і і і і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 87 = Меню Options (Параметры) ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іLanguage (Язык) іЗадает использование выражений і і іязыка из исходного модуля. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іMacros (Maкрокоманды) і і і Create (Создание) іОпределяет строковую і і імакрокоманду. і і Stop Recording іЗавершает сеанс записи. і і (Завершить запись) і і і Remove (Удалить) іУдаляет строковую макрокоманду. і і Delete All (Удалить іУдаляет все строковые і і все) імакрокоманды. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDisplay Options (Режим выводаіПозволяет вам задать параметры і іна экран) івывода (переключение экрана, і і іразмер, табуляция) і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іPath for Source (Маршрут дос-іСписок каталогов исходных файлов.і ітупа к исходным файлам) і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іSave Options (Сохранение іСохраняет параметры, макрокомандыі іпараметров) іи окна на диске. і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іRestore Options (Восстанов- іВосстанавливает параметры с і іление параметров) ідиска. і і і і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 88 = Меню Window (Окно) ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іZoom (Переключение размера) іУвеличивает размер окна до і і іразмера всего экрана и обратно. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іNext (Следующее) іОткрывает и активизирует на і і іэкране следующее последовательноеі і іокно. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іNext Pane (Следующая область)іВыполняет переход в следующую і і іобласть окна. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іSize/Move (Перемещение/ іПеремещает текущее окно или і іИзменение размера) іизменяет его размер. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іIconsize/Restore (Cжатие/ іСжимает окно до размера символа і івосстановление) іили восстанавливает его. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іClose (Закрыть) іСтирает текущее окно. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іUndo Close (Отмена закрытия) іОтменяет последнюю команду і і істирания. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDump Pane to Log (Вывод іЗаписывает текущее окно в окно і іобласти в протокол регистра- ірегистрации (Log). і іции) і і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іUser Screen (Экран пользова- іВыводит экран вывода вашей і ітеля) іпрограммы. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іНумерованный список окон іВыводится для активизации список і і і9 открытых окон. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ TDeb 3.0 #2-3 = 89 = і і і іWindow Pick (Выбор окна) іВыбирает окно из списка открытых і і іокон. і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Меню Help (Справка) ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іIndex (Оглавление) іВыводит на экран оглавление і і іоперативного справочника. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іPrevious Topic (Предыдущая іВыводит последний справочный і ітема) іэкран. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іHelp on Help (Информация по іВыводит на экран информацию по і ісправочнику) ісправочной системе. і і і і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 90 = Команды локальных меню ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для текущего окна вызвать всплывающее или "локальное" меню можно с помощью клавиш Alt-F10. Если разрешено использовать сок- ращения с клавишей Ctrl (разрешить это можно с помощью программы установки TDINST), то к отдельным элементам этого меню можно об- ратиться непосредственно с помощью клавиши Ctrl и первой буквы нужного элемента (команды) меню (нажав их одновременно). Примечание: Каждый тип окна и каждая область окна со- держат разные локальные меню. В следующих разделах описываются локальные меню для каждого окна и области. Примечание: Меню в данном разделе для облегчения поиска упорядочены по алфавиту. Некоторые области в своих локальных меню могут содержать об- щие команды (их сокращения для оперативных клавиш). В следующих разделах эти специальные клавиши описываются перед командами меню для той области, к которой они относятся. Во многих областях окон клавиша Enter представляет собой сокращение для проверки или из- менения текущего (подсвеченного) элемента. Клавиша Del часто вы- зывает команду локального меню, которая удаляет подсвеченный эле- мента. Некоторые области позволяют вам начать ввод букв или цифр без предварительного вызова команды локального меню. В этом слу- чае выводится рамка (окно) подсказки, куда можно вводить данные. Локальное меню окна Breakpoints (Точки останова) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно Breakpoints содержит две области: область списка (сле- ва) и область детализации (справа). Локальное меню имеет только область списка. ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іSet Option (Задать параметры)іЗадает действие, по которому і і ісрабатывает точка і і іостанова, условия, счетчик і і іпроходов, разрешает или і і ізапрещает данную точку і і іостанова. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іAdd (Добавить) іДобавляет новую точку останова. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іRemove (Удаление) іУдаляет текущую (подсвеченную) і TDeb 3.0 #2-3 = 91 = і іточку останова. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDelete All (Удалить все) іУдаляет все точки останова. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іInspect (Проверка) іПросмотр кода, где находится і і іточка останова. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іGroup (Группа) іРабота с группами точек останова.і і і і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ В данном окне в качестве сокращения команды Remove ф (Удале- ние) используется клавиша Del. TDeb 3.0 #2-3 = 92 = Меню окна CPU (ЦП) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно CPU (Центральный процессор) имеет пять (шесть для от- ладчика TDW) областей (область кода, область данных, область сте- ка, область регистров и область флагов), и в каждой области име- ется локальное меню (шестая область - область селектора). Область кода ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іGoto (Переход) іВыводит на экран исходный код по новому і і іадресу. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іOrigin (Начало) іВыводит на экран код по адресу cs:ip. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іFollow (Следовать) іВыводит на экран код по целевому адресу і і іJMP или CALL. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іCaller (Вызывающая іВыводит на экран код вызывающей функции. і іфункция) і і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іPrevious (Предыдущий)іВыводит на экран код по последнему і і іадресу. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іSearch (Поиск) іВыполняет поиск инструкций или байт. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іView Source (ПросмотріПереключается в окно Module (Модуль). і іисходного кода) і і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іMixed (Смешанный) іNo/Yes/Both - Нет/Да/Оба: выводимый і і іисходный код чередуется с і і іинструкциями Ассемблера. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іNew CS:IP (Новое іУстанавливает CS:IP для выполнения новогоі ізначение CS:IP) іадреса. і і і і TDeb 3.0 #2-3 = 93 = ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іAssemble (Ассембли- і і ірование) і і і In byte (ВводіСчитывает байт по адресу ввода-вывода. і і байта) і і і Out Byte (Вы-іЗаписывает байт по адресу ввода-вывода. і і вод байта) і і і Read Word іСчитывает слово из адреса ввода-вывода. і і (Считать і і і слово) і і і Write Word іЗаписывает слово по адресу ввода-вывода. і і (Записать і і і слово) і і і і і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Вместо команды локального меню Assemble (Ассемблирование) можно использовать сокращенный вариант: набор любого символа. Область селектора ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іSelector (Селектор) іПозволяет вам ввести новый селектор и і і іперейти на него. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іExamine (Проверка) іВыводит содержимое области памяти, на і і ікоторую ссылается селектор, в области і і ікода или в области данных, в зависимости і і іот типа содержимого. і і і і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 94 = Область данных ЪДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і і Goto (Переход) іВыводит на экран данные по новому адре-і і ісу. і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і Search (Поиск) іВыполняет поиск строки или байт. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і Next (Следующий) іВыполняет повторный поиск (следующего і і івхождения). і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і Change (Изменение) іИзменяет байты данных по адресу курсо- і і іра. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і Follow (Следовать) іСледует по цепочке указателя (ближний і і ітип или дальний тип). і і і і і Near Code (Ближ- іСледует по цепочке указателя (ближний і і ний код) ітип). Устанавливает область кода под і і ікурсором в ближний адрес. і і і і і Far Code (Даль- іСледует по цепочке указателя (дальний і і ний код) ітип). Устанавливает область кода под і і ікурсором в дальний адрес. і і і і і Offset to Data іСмещение данных. Устанавливает область і і (Смещение данных)ікода в ближний адрес под курсором. і і і і і Base Segment:0 іУстанавливает область данных в начало і і to Data (Базовый ісегмента, который содержит адрес под і і сегмент данных) ікурсором. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і Previous (Предыдущий) іВыводит на экран данные по последнему і і іадресу. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і Display As (Режим і і і вывода) і і і Byte (Байт) іНа экран выводятся шестнадцатиричные і і ібайты. і і і і і Word (Слово) іНа экран выводятся шестнадцатиричные і і іслова. і TDeb 3.0 #2-3 = 95 = і і і і Long (Длинный)іНа экран выводятся шестнадцатиричные і і і32-битовые длинные слова. і і і і і Comp (Cложный)іНа экран выводятся 8-байтовые целые і і іПаскаля (тип comp). і і і і і Float (С пла- іНа экран выводятся короткие (4 байта) і і вающей точкой)ічисла с плавающей точкой (вещественный і і ітип с одинарной точностью Паскаля, тип і і іfvloat в Си). і і і і і Real (Вещест- іНа экран выводятся 6-байтовые числа с і і венный) іплавающей точкой (вещественный тип і і іПаскаля). і і і і і Double (С іНа экран выводятся 8-байтовые числа с і і двойной точ- іплавающей точкой (двойная точность в Сиі і ностью) іи Паскале). і і і і і Extended (С іНа экран выводятся 10-байтовые числа с і і расширенной іплавающей точкой (тип extended языка і і точностью) іПаскаль, long double языка Си). і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і Block (Блок) і і і Clear (Очист- іОчищает блок памяти. і і ка) і і і і і і Move (Переме- іПеремещает блок в памяти. і і мещение) і і і і і і Set (Присваи- іПрисваивает блоку памяти значение і і сваивание) і(побайтно). і і і і і Read (Считы- іВыполняет чтение из файла в память. і і тывание) і і і і і і Write (Запись)іЗаписывает из памяти в файл. і АДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Вместо команды локального меню данной области Change (Изме- нение) можно использовать сокращенный вариант: набор любого сим- вола. Область флагов ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іToggle (Переключение)іУстанавливает или сбрасывает (очищает) і і ітекущий (подсвеченный) флаг. і і і і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 96 = В качестве сокращений данной команды можно использовать кла- виши Enter или "пробел". Область регистров ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іIncrement (Увеличение)іДобавляет 1 к текущему (подсвеченному) і і ірегистру. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDecrement (Уменьшение)іВычитает 1 из текущего (подсвеченного) і і ірегистра. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іZero (Очистка) іОчищает содержимое текущего регистра. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іChange (Изменение) іПрисваивает текущему (подсвеченному) і і ірегистру новое значение. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іRegister 32-bit (32- іNo/Yes (Да/Нет): переключает экран в і іразрядный регистр) ірежим вывода 32-разрядных регистров. і і і і АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Вместо команды локального меню данной области Change (Изме- нение) можно использовать сокращенный вариант: набор любого сим- вола. TDeb 3.0 #2-3 = 97 = Область стека ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і і Goto (Переход) іВыводит на экран содержимое стека по і і іновому адресу. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і Origin (Начало) іВыводит на экран данные по адресу SS:SP.і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і Follow (Следовать) іВыводит код, на который указывает і і ітекущий элемент. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і Previous (Предыдущий)іВосстанавливает на экране вывод по і і іпоследнему адресу. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і і Change (Изменение) іПозволяет вам редактировать информацию. і і і і АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Вместо команды локального меню данной области Change (Изме- нение) можно использовать сокращенный вариант: набор любого сим- вола. TDeb 3.0 #2-3 = 98 = Окно Dump (Дамп) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно Dump идентично области данных окна CPU (ЦП). Их локаль- ные меню также эквивалентны. Меню окна Execution History ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно Execution History (Протокол выполнения) имеет две об- ласти, каждая из которых имеет свое локальное меню: область Instructions (область инструкций) и область Keystroke Recording (область регистрации нажатий клавиш). Область инструкций ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Область инструкций показывает уже выполненные команды, кото- рые вы можете изучать или для которых можно выполнить "откат". ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іInspect іПереход к выделенной команде. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іReverse Execute іРеверсирует выполнение программы до і і ікоманды, выделенной в области і і іинструкций. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іFull History іРазрешает (On) или отменяет (Off) і і іреверсивное выполнение. і і і і АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 99 = Область регистрации нажатий клавиш ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Область Keystroke Recording показывает записанные нажатия клавиш. Вы можете использовать их для изучения исходного кода или при перезапуске программы. ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іInspect іПоказывает строку исходного кода, в ко- і і іторой была нажата клавиша. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іKeystroke Restore іПерезагружает и выполняет вашу программу і і ідо контекста, относящегося к выделенному і і інажатию клавиши (это может оказаться по- і і ілезным, если средство записи протокола і і івыполнения (Execution History) было вык- і і ілючено. і і і і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Окно File (Файл) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В окне File (Файл) выводится в текстовом или шестнадцатирич- ном виде содержимое файла на диске. ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іGoto (Переход) іВыводится строка с указанным номером илиі і ішестнадцатиричным смещением. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іSearch (Поиск) іВыполняет поиск строки или байт данных. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іNext (Следующий) іВыполняет повторный поиск (следующего і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDisplay As (Режим іAsciiіHex (В коде ASCII/ і івывода) ішестнадцатиричный): задает режим вывода і і іфайла. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іFile (Файл) іПереключает на вывод нового файла. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ TDeb 3.0 #2-3 = 100 = і і і іEdit (Редактирование)іРедактирует файл или изменяет данные в і і ітекущей позиции курсора. і і і і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Вместо команды локального меню Search (Поиск) можно исполь- зовать сокращенный вариант: набор любого символа. Локальное меню окна Log (Регистрация) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В окне Log (Регистрация) выводятся сообщения, переданные для регистрации (протокол). ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іOpen Log File (Открыть файл іНачинает запись протокола в файл.і ірегистрации) і і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іClose Log File (Закрыть файл іПрекращает запись протокола в і ірегистрации) іфайл. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іLogging (Регистрация) іNoіYes (ДаіНет): включает или і і івыключает регистрацию. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іAdd Comment (Добавить ком- іЗаписывает в протокол регистрацииі іментарий) ікомментарий пользователя. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іErase Log (Стереть протокол) іСтирает все зарегистрированные і і ісообщения. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDisplay Windows Info іВыводит диалоговое окно Windows і і(Вывод информации Windows) іInformation (Информация Windows),і і іиз которого выбрать, что вы і і іхотите выводить на экран і і і(глобальную динамически і і іраспределяемую область памяти, і і ілокальную динамически і і іраспределяемую область памяти илиі і імодуль). і і і і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 101 = Вместо команды локального меню Add Comment (Добавить коммен- тарий) можно использовать сокращенный вариант: набор любого сим- вола. TDeb 3.0 #2-3 = 102 = Окно Module (Модуль) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В окне Module (Модуль) выводится содержимое исходного файла программного модуля. ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іInspect (Проверка) іВыводится содержимое переменной под і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іWatch (Просмотр) іК списку выражений просмотра добавляется і і іпеременная под курсором. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іModule (Модуль) іВыводит на экран другой модуль. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іFile (Файл) іВыводит на экран другой файл. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іPrevious (Предыдущий)іВыводит на экран последний модуль и і і іпозицию. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іLine (Строка) іВыводит строку в модуле с указанным і і іномером. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іSearch (Поиск) іВыполняет поиск текстовой строки. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іNext (Следующий) іВыполняет повторный поиск (ищет следующееі і івхождение строки). і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іOrigin (Начало) іВыводит на экран программу по текущему і і іадресу. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іGoto (Переход) іВыводит на экран исходный код или і і іинструкции по указанному адресу. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ TDeb 3.0 #2-3 = 103 = і і і іEdit (Редактирование)іЗапускает редактор для редактирования і і іисходного файла. і і і і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Вместо команды локального меню Goto (Переход) можно исполь- зовать сокращенный вариант: набор любого символа. Окно Windows Messages ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно Windows Messages (Сообщения Windows) имеет три области: область выбора окна (Window Selection), область класса сообщения (Message Class) и область сообщений (Messages). TDeb 3.0 #2-3 = 104 = Область выбора окна ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Эта область имеет следующие команды локального меню: ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іAdd (Добавление) іДобавляет имя окна или логический номер.і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іRemove (Удаление) іУдаляет выбранное окно. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDelete All (Удалить іУдаляет все выбранные окна. і івсе) і і і і і АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Ввод любого символа является сокращенной формой команды Add (Добавление) локального меню данной области. Клавиша Del или комбинация Ctrl-Y - это сокращение для ко- манды локального меню Remove. TDeb 3.0 #2-3 = 105 = Область класса сообщений ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Эта область имеет следующие команды локального меню: ЪДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іAdd (Добавление) іДобавляет класс сообщений или отдельноеі і ісообщение. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іRemove іУдаляет выбранный класс сообщений или і і(Удаление) іотдельное сообщение. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDelete All іУдаляет все выбранные классы или і і(Удалить все) іотдельные сообщения. і і і і АДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Ввод любого символа является сокращенной формой команды Add локального меню данной области. Клавиша Del или комбинация Ctrl-Y - это сокращение для ко- манды локального меню Remove. Область сообщений ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Эта область имеет следующие команды локального меню: ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іSend to log window іПосылает все принятые сообщения в окно і і(Пересылка в окно ірегистрации, чтобы сохранить их в і ірегистрации) іпротоколе регистрации. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іErase log (Стирание) іУдаляет все сообщения в области. і і і і АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 106 = Окно Clipboard ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В окне Clipboard выводятся все элементы, которые вы скопиро- вали в карман. Оно имеет единственную область со следующими ко- мандами локального меню: ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іInspect (Проверка) іПереводит вас в то окно, из которого былі і іскопирован элемент, благодаря чему вы і і іможете его проверить. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іRemove (Удаление) іУдаляет подсвеченный элемент. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDelete All (Удалить іУдаляет все элементы окна Clipboard. і івсе) і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іFreeze ("Заморозить") іПриостанавливает изменение значение і і і(сохраняется текущее значение элемента).і і і і АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Окно Numeric Proseccor (Сопроцессор) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно Numeric Processor (Арифметический сопроцессор) содержит три области: область регистров, область состояния и область уп- равления. TDeb 3.0 #2-3 = 107 = Область регистров ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В качестве сокращенных вариантов команд локального меню дан- ной области можно использовать следующие клавиши: ЪДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іZero (Ноль) іОчищает подсвеченный регистр. і ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іEmpty (Пусто) іУстанавливает подсвеченный регистр в пустое і і ізначение. і ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іChange іУстанавливает подсвеченный регистр в заданное і і(Изменение) ізначение. і АДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Вместо команды локального меню данной области Change (Изме- нение) можно использовать сокращенный вариант: набор любого сим- вола. Область состояния ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД ЪДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і і Toggle (Переключение) і Циклически изменяет значение флага. і АДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ В качестве сокращенного варианта данной команды локального меню можно использовать просто нажатие клавиши Enter или пробел. Область управления ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД ЪДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і і Toggle (Переключение) і Циклически изменяет значение флага. і і і і АДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ В качестве сокращенного варианта данной команды локального меню можно использовать просто нажатие клавиши Enter или пробел. Окно Hierarchy (Иерархия) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно Hierarchy (Иерархия) содержит две области: область TDeb 3.0 #2-3 = 108 = списка типов объектов и область дерева иерархии. Область списка типов объектов/классов ЪДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іInspect (Проверка) іВыводит содержимое подсвеченного типа і і іобъекта/класса і і і і ГДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іTree (Дерево) іПереводит вас в область дерева иерархии. і і і і АДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 109 = Область дерева иерархии ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іInspect (Проверка) іВыводит содержимое подсвеченного типа і і іобъекта/класса. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іParents (Порождающие іЕсли вы выполняете программу с і іобъекты/классы) імножественным наследованием, выполняет і і іпереключение области дерева порождающих і і іобъектов/классов. і і і і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Область дерева порождающих объектов/классов ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іInspect (Проверка) іВыводит содержимое подсвеченного типа і і іобъекта. і і і і АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Меню окна Registers (Регистры) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно Registers (Регистры) идентично областям регистров и флагов окна CPU (ЦП). Его локальные меню идентичны локальным меню области регистров и области флагов. TDeb 3.0 #2-3 = 110 = Окно Stack (Стек) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В области стека выводятся активные в данный момент процеду- ры. ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іInspect (Проверка) іВыводит исходный код текущей і і іподсвеченной) процедуры. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іLocals (Локальные) іВыводит локальные переменные процедуры. і і і і АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ В качестве сокращенного варианта команды локального меню Inspect можно использовать просто нажатие клавиши Enter. Окно Variables (Переменные) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Это окно разделено на две области, у каждой из которых име- ется свое локальное меню: область глобальных идентификаторов и область локальных идентификаторов. Область глобальных идентификаторов ЪДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іInspect іОтображает значение выделенной і і іпеременной. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іChange іЗаменяет значение выделенной і і іпеременной. і і і і ГДДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іWatches іДобавляет выделенный идентификатор в і і іокно Watches. і і і і АДДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Нажатие клавиши Enter является сокращенной формой команды Inspect локального меню данной области. TDeb 3.0 #2-3 = 111 = Область локальных идентификаторов ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іInspect іОтображает значение выделенной і і іпеременной. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іChange іЗаменяет значение выделенной і і іпеременной. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іWatches іДобавляет выделенный идентификатор в і і іокно Watches. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іShow іИзменяет модули, или показывает і і Static ітолько статические переменные, і і Auto ітолько динамические переменные, і і Both іили и то, и другое. і і Module іИзменяет текущий модуль. і і і і АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ В качестве сокращенного варианта команды локального меню Inspect можно использовать просто нажатие клавиши Enter. TDeb 3.0 #2-3 = 112 = Окно Watches (Просмотр) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно Watches (Просмотр) содержит единственную область, в ко- торой выводятся имена и значения просматриваемых переменных. ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іWatch (Просмотр) іДобавляет переменную в область просмотра.і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іEdit (Редактирование)іПозволяет редактировать переменную. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іRemove (Удаление) іУдаляет подсвеченную переменную. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDelete All (Удалить іУдаляет все переменные просмотра. і івсе) і і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іInspect (Проверка) іВыводит содержимое подсвеченной і і іпеременной. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іChange (Изменение) іИзменяет содержимое подсвеченной і і іпеременной. і і і і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ В качестве сокращений команд данного локального меню можно использовать следующие клавиши: ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Клавиша Функция ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Любой символ Просмотр Enter Редактирование Del Удаление ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД TDeb 3.0 #2-3 = 113 = Окно Inspector (Проверка) ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В окне Inspector (Проверка) выводится содержимое элемента данных. ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іRange (Диапазон) іПозволяет выбрать для проверки элементы і і імассива. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іChange (Изменение) іИзменяет значение подсвеченного элемента.і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іInspect (Проверка) іОткрывает для подсвеченного элемента і і іновое окно Inspector. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDescend (Нисходящий) іРасширяет подсвеченный элемент в данное і і іокно проверки. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іNew Expression (НовоеіПроверяет в данном окне Inspector новое і івыражение) івыражение. і і і і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іType Cast (ПриведениеіПриводит тип подсвеченного элемента в і ітипа) ісоответствие с новым элементом. і і і і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Окно проверки типа объекта/класса ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно проверки типа объекта/класса (Object Type/class Inspector) имеет две области, в которых выводится содержимое (по- ля данных или элементы класса либо методы или функции-элементы). Локальные меню обеих областей совпадают, но сильно отличаются от локальных меню обычных окно проверки (Inspector). TDeb 3.0 #2-3 = 114 = ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іInspect (Проверка) іВыводит содержимое подсвеченного типа і і іобъекта/класса. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іHierarchy (Иерархия) іВозвращает вас в окно иерархии. і і і і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іShow Inherited (Вывод іПереключает между выводом содержимого і інаследования) івсех объектов или классов и содержимым, і і іописанным в текущем объекте. і і і і АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 115 = Окно проверки экземпляра объекта ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Окно проверки экземпляра объекта/класса (Object/Class Instance Inspector) содержит три области, из которых только пер- вая область имеет локальное меню (в третьей области выводится только тип объекта или класса, к которому относится данный эк- земпляр). Локальные меню первых двух областей совпадают и содер- жат следующие команды: Клавиатурные команды области текста Таблица 13.2 ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і і і іRange (Диапазон) іВыбирает элементы массива для проверки. і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іChange (Изменение) іИзменяет значение подсвеченного элемента.і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іMethods (Методы) іРазрешает или запрещает вывод всех і і іметодов в средней области. і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іShow Inherited іРазрешает или запрещает вывод вывод і і(Вывод наследования) ісодержимого всех объектов и содержимого, і і іописанного в текущем объекте/классе і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іInspect (Проверка) іОткрывает новое окно Inspector для і і іподсвеченного элемента. і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іDescend (Спуск) іРасширяет подсвеченный элемент в данное і і іокно Inspector. і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іType Cast (ПриведениеіПриводит тип подсвеченного элемента к і ітипа) іновому типу. і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і і і іHierarchy (Иерархия) іВозвращает вас в окно иерархии объектов. і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Области текста ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Это общее название тех областей, в которых на экран выводит- TDeb 3.0 #2-3 = 116 = ся содержимое текстового файла. Текущая позиция в файле отмечена мерцающим курсором. В следующей таблице приведен список всех ко- манд: Клавиатурные команды области списка Таблица 13.3 ЪДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і Клавиша і Функция і ГДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і Ins і Отмечает блок текста і і Стрелка вверхі Перемещает вверх на одну строку і і Стрелка вниз і Перемещает на одну строку вниз і і Ctrl-Д> і Перемещает на следующее слово і і Ctrl-<- і Перемещает на предыдущее слово і і Home і Перемещает к началу строки і і End і Перемещает к последнему символу строки і і PgUp і "Прокручивает" изображение на один экран вверх і і PgDn і "Прокручивает" изображение на один экран вниз і і Сtrl-Home і Переводит на верхнюю строку области і і Сtrl-End і Переводит на нижнюю строку области і і Сtrl-PgUp і Переводит первую строку файла і і Сtrl-PgDn і Переводит на последнюю строку файла і АДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Если вы не используете сокращения с клавишей Ctrl, то можно также для перемещения в области текста использовать управляющие клавиши, аналогичные редактору WordStar. TDeb 3.0 #2-3 = 117 = Области списков ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Области списков - это общее название области, где перечисля- ется информация, которую вы можете "пролистывать". На текущую по- зицию в списке указывает подсветка. Приведем список всех доступ- ных вам команд: ЪДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і Клавиша і Функция і ГДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і Стрелка вверх і Перемещение вверх на один элемент і і Стрелка вниз і Перемещение вниз на один элемент і і Home і Переход к началу строки і і PgUp і "Прокрутка" вверх на один экран і і PgDn і "Прокрутка" вниз на один экран і і Ctrl-Home і Переход к верхней строке области списка і і Ctrl-End і Переход к нижней строке области списка і і Ctrl-PgUp і Переход к первому элементу списка і і Ctrl-PgDn і Переход к последнему элементу списка і і Backspace і Возврат назад на один символ при і і і сравнении і і Буква і Поиск с увеличением (выбор при наборе) і АДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Можно также для перемещения в области текста использовать управляющие клавиши, аналогичные редактору WordStar. TDeb 3.0 #2-3 = 118 = Команды в окнах подсказки ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В следующей таблице перечислены все команды, которые можно использовать внутри окна подсказки, в окне ввода или в окне спис- ка: Клавиатурные команды диалогового окна Таблица 13.4 ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї іКлавиша і Функция і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ іСтрелка вверх і Перемещение вверх на одну запись і іСтрелка вниз і Перемещение вниз на одну запись і іСтрелка вправо і Перемещение вправо на один символ і іСтрелка влево і Перемещение влево на один символ і іCtrl-Д> і Перемещение к следующему слову і іCtrl-<- і Перемещение к предыдущему слову і іHome і Переход к началу строки і іEnd і Переход к концу строки і іPgUp і "Прокрутка" вверх на один экран і іPgDn і "Прокрутка" вниз на один экран і іCtrl-Home і Переход к верхней строке области спискаі іCtrl-End і Переход к нижней строке области списка і іCtrl-PgUp і Переход к первому элементу списка і іCtrl-PgDn і Переход к последнему элементу списка і іBackspace і Удаление символа перед курсором і іEnter і Воспринимается и обрабатывается то, і і і что вы ввели і іDel і Удаление одного символа после курсора і іEsc і Отмена подсказки и возврат в меню і АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 119 = Команды перемещения окна ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В следующей таблице показаны клавиши, с помощью которых вы можете изменять позицию и размер окна на экране. Клавиатурные команды перемещения окна Таблица 13.5 ЪДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і Клавиша і Функция і ГДДДДДДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ і Ctrl-F5 і Переключение режима позиционирования і і і окна і і Cтрелка вверх і Перемещение окна вверх на одну строку і і Стрелка вниз і Перемещение окна вниз на одну строку і і Стрелка влево і Перемещение окна влево на одну позицию і і Стрелка вправо і Перемещение окна вправо на одну позицию і і Shift-Стрелка вверх і Перемещение окна вверх на несколько і і і строк і і Shift-Стрелка вниз і Перемещение окна вниз на несколько строкі і Shift-Д> і Перемещение окна вправо на несколько і і і cтрок і і Shift-<- і Перемещение окна влево на несколько і і і строк і і Home і Перемещение в левую часть экрана і і End і Перемещение в правую часть экрана і і PgUp і Перемещение в верхнюю строку экрана і і PgDn і Перемещение к нижней строке экрана і і Enter і Фиксируется текущая позиция і і Esc і Отмена команды позиционирования окна і АДДДДДДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ Трафаретные символы, используемые при поиске ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Трафаретные символы при поиске можно использовать в двух случаях: - при вводе имени файла, который нужно загрузить и прове- рить; - при вводе текстового выражения, поиск которого нужно выполнить в области текста. Знак вопроса (?) в выражении поиска совпадает с любым оди- ночным символом. Звездочка (*) в выражении поиска совпадает с 0 или более символов. TDeb 3.0 #2-3 = 120 = Полное дерево меню ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД На Рис. 13.1 показана полная структуру спускающихся меню Турбо отладчика TD. ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї іЁ File Edit View Run Breakpoints Data Options Window Help і АДВДДВДДВДДДДВДДДДВДДДДДДДВДДДДДДДДДВДДДДДДВДДДДДДДДВДДДДДДВДДДДЩ і і і і і і і і і і і і і і і і і і і АДДДДї і і і і і і і і АДДДДДДДДДДїі і і і і і і і АДДДДДДДДДДДДДДДДДДїіі і і і і і і АДДДДДДДДДДДДДДДДДДДДДДДДїііі і і і і і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДїіііі і і і і АДДДДДДДДДДДДДДДДДДДДДДДДДДї ііііі і і і АДДДДДДДДДДДДї і ііііі і і АДДДДДДДДДДДДДДДДїі і ііііі і АДДДДДДДДДДДДДДДДДДїіі v ііііі АДДДДДДї ііі ЪДДДДДДДДДДДДДДДДДДДДДДДДДДї ііііі і ііі і Run і ііііі v ііі іДДДДДДДДДДДДДДДДДДДДДДДДДДі ііііі ЪДДДДДДДДДДДДДДДДДДїііі і Run F9 і ііііі і Ё (System) іііі і Go to cursor F4 і ііііі іДДДДДДДДДДДДДДДДДДіііі і Trace Into F7 і ііііі і Repaint Desktop іііі і Step Over F8 і ііііі і Restore Standard іііі і Execute to... Alt-F9 і ііііі іДДДДДДДДДДДДДДДДДДіііі і Until Return Alt-F8 і ііііі і About... іііі і Animate... і ііііі АДДДДДДДДДДДДДДДДДДЩііі і Back Trace Alt-F4 і ііііі ЪДДДДДДДДДДДДДДДДДДДДДДДЩіі і Instruction Trace Alt-F7 і ііііі і ЪДДДДДДДДДДДЩі іДДДДДДДДДДДДДДДДДДДДДДДДДДі ііііі і v і і Arguments... і ііііі і ЪДДДДДДДДДДДДДДДДДДї і і Program reset Ctrl-F2 і ііііі і і File і і АДДДДДДДДДДДДДДДДДДДДДДДДДДЩ ііііі і іДДДДДДДДДДДДДДДДДДі і ЪДДДДДДДДДДДДДДДЩіііі і і Open... і і і іііі і і Change dir... і і v ЪЩііі і і Get Info... і і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДї і ііі і і і і і Breakpoints і і ііі і і і і іДДДДДДДДДДДДДДДДДДДДДДДДДДі і ііі і іДДДДДДДДДДДДДДДДДДі і і Toggle F2 і і ііі і і Symbol Load... і і і At... Alt-F2 і і ііі і і і і і Changed memory global... і і ііі і іДДДДДДДДДДДДДДДДДДі і і Expression true global...і і ііі і і Quit Alt-X і і і Handware Breakpoint... і і ііі і АДДДДДДДДДДДДДДДДДДЩ і і Delete all і і ііі і ЪДДДДДДДДДДДЩ АДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і ііі і і ЪДДДДДДДДДДДДДДЩ ііі і v і ііі і ЪДДДДДДДДДДДДДДДДДДДї v ііі і і View і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДїііі і іДДДДДДДДДДДДДДДДДДДі і Data іііі TDeb 3.0 #2-3 = 121 = і і Breakpoints і іДДДДДДДДДДДДДДДДДДДДДДДДДДДДДіііі і і Stack і і Inspect... іііі і і Log і і Evaluateіmodify... Ctrl-F4 іііі і і Watches і і Add watch... Ctrl-F7 іііі і і Variables і і Function return іііі і і Module... F3 і АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩііі і і File... і ііі і і CPU і ЪДДДДДДДДЩіі і і Dump і ЪДДДДДДДДДДДДї і іі і і Registers і ЪДДі Module... і і іі і і Numeric Processor і і і Dump і і іі і і Execution History і і і File... і і іі і і Hierarchy і і АДДДДДДДДДДДДЩ і іі і і Windows messages і і і іі і і Another >іДДЩ і іі і АДДДДДДДДДДДДДДДДДДДЩ ЪДДДДДДДДДДДДДДДДДДДДДДДДЩ іі і ЪДДДДДДДДЩ ЪДДДДДДДДДЩі і v і і і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДї v і і і Options і ЪДДДДДДДДДДДДДДДДДДДДїі і іДДДДДДДДДДДДДДДДДДДДДДДДДДДі і Window іі і і Language... Source і іДДДДДДДДДДДДДДДДДДДДіі і і Macros >іДДї і Zoom F5 іі і і Display options... і і і Next F6 іі і і Path for source... і і і Next pane Tab іі і і Save options... і і і Size/move Ctrl-F5 іі і і Restore options... і і і Iconsize/restore іі і АДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і і Close Alt-F3 іі і ЪДДДДДДДДДДДДДДДДЩ і Undo close Alt-F6 іі і і іДДДДДДДДДДДДДДДДДДДДіі і v і Dump pane to log іі і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДї і User screen Atl-F5 іі і і Create... Alt = і і 1 Module TPDEMO іі і і Stop recording Alt - і і 2 Watches іі і і Remove і АДДДДДДДДДДДДДДДДДДДДЩі і і Delete all і ЪДДДДДДДДДДДДДЩ і АДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і АДДДДДДДДДДДДДДї v і ЪДДДДДДДДДДДДДДДДДДДДДДДї v і Help і ЪДДДДДДДДДДДДДДДДДДДДДДДї іДДДДДДДДДДДДДДДДДДДДДДДі і Edit і і Index Shift-F1 і іДДДДДДДДДДДДДДДДДДДДДДДі і Previous topic Alt-F1 і і Copy Shift-F3 і і Help on help і і Paste Shift-F4 і АДДДДДДДДДДДДДДДДДДДДДДДЩ і Copy to Log і і Dump pane to log і АДДДДДДДДДДДДДДДДДДДДДДДЩ TDeb 3.0 #2-3 = 122 = Глава 14. Отладка программы ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Отладка программы аналогична всем другим этапам реализации программы - это наполовину искусство, наполовину наука. Существу- ют специальные процедуры, которые можно использовать для отслежи- вания ошибки, однако, чтобы сократить этот процесс, требуется также хорошая интуиция. В большинстве отлаживаемых вами программ лучшее, что вы мо- жете сделать - это быстро найти источник ошибок в исходном коде. Для этого нужно освоить соответствующие методы, а также изучить такие способы, которые позволят избежать повторного появления ошибок. Мы начнем с того, что посмотрим, с чего можно начать отладку программы, которая не работает должным образом. В данной главе мы обсудим также различные подходы к отладке, разные типы ошибок, которые могут встречаться в программе, и предложим методы проверки программы, позволяющие убедиться в пра- вильности ее работы. Давайте посмотрим, с чего можно начать, когда программа не работает корректно. Когда что-то не работает ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Прежде всего не следует впадать в панику. Даже наиболее опытные программисты редко пишут программы, которые начинают ра- ботать с первого раза. Чтобы избежать напрасной траты времени на долгие и бесплод- ные поиски ошибки, постарайтесь побороть стремление случайно уга- дать, где находится ошибка. Лучшим методом здесь будет универ- сальный принцип "разделяй и властвуй". Нужно сделать ряд предположений, проверив каждое из них по очереди. Например, вы можете предположить: "Ошибка должна возни- кать перед вызовом функции xyz". Затем нужно проверить это пред- положение, остановив программу перед вызовом функции xyz и пос- мотрев, есть ли ошибка. Если вы обнаружите ошибку в этой точке, можно сделать следующее предположение, что ошибка возникает в программе где-то раньше. С другой стороны, если при вызове функции xyz все выглядит прекрасно, ваше предположение оказалось неверным. Нужно изменить это предположение на следующее: "Ошибка возникает где-то после вызова функции xyz. Выполнив ряд аналогичных проверок, вы скоро найдете ту часть программы, где возникает ошибка. Это прекрасно, скажете вы, но как же определить после оста- TDeb 3.0 #2-3 = 123 = новки программы, что она ведет себя правильно? Один из наилучших путей проверки поведения программы состоит в анализе значений пе- ременных и объектов данных программы. Например, если у вас есть подпрограмма, очищающая массив, вы можете проверить ее работу, остановив программу после выполнения данной подпрограммы и прове- рив затем каждый элемент массива, чтобы убедиться, что он очищен. Стиль отладки ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД У каждого свой стиль как разработки программы, так и ее от- ладки. Те рекомендации по отладке, которые мы здесь приводим, яв- ляются лишь отправными пунктами, которые позволят вам сформиро- вать свой подход. В многих случаях на метод отладки влияет предполагаемое ис- пользование (назначение) программы. Некоторые программы вы пишете для себя, либо они будут использованы только один или два раза для выполнения конкретной задачи. Для таких программ разносторо- нее тестирование всех их элементов было бы напрасной тратой вре- мени, особенно, если после проверки ее выходных данных вы видите, что программа работает правильно. Для тех программ, которые пред- полагается распространять, или для тех, которые выполняют задачу, правильность которой трудно определить с помощью проверки, может оказаться желательным более строгое тестирование. Полное выполнение ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для простых программ лучший подход, вероятно, состоит в том, чтобы просто запустить программу и посмотреть, что получилось. Если при такой проверке будут обнаружены ошибки, вы можете "сде- лать шаг назад" и запустить программу с максимально простыми входными данными, чтобы проверить затем ее вывод. Затем можно пе- рейти к проверке с более сложными входными данными, и так далее, пока выходная информация не станет неверной. Это даст вам хорошее представление о том, насколько корректно работает программа. Последовательное тестирование ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Если вы хотите полностью убедиться, что программа работает правильно, нужно проверить отдельные подпрограммы, а также убе- диться, что программа выдает ожидаемые результаты для некоторых тестовых входных данных. Это можно сделать двумя способами: можно выполнить проверку каждой подпрограммы, включив ее в програм- му-тест, которая вызывает подпрограмму с тестовыми входными дан- ными, или использовать отладчик для пошагового выполнения каждой подпрограммы, пока не будет выполнена вся программа. TDeb 3.0 #2-3 = 124 = Типы ошибок ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Ошибки в программе можно разбить на две больших категории: ошибки, относящиеся к используемому языку (Си, Паскалю или Ас- семблеру), и ошибки, общие для всех языков программирования и операционных сред. По мере отладки программы вы изучите как специфические для языка конструкции, которые могут приводить к неприятностям, так и более общие ошибки программирования, которые вы сделали. Это зна- ние можно использовать в последующем, чтобы постараться избежать повторения таких ошибок. Кроме того, это послужит хорошей базой для того, чтобы быстрее обнаруживать ошибки в следующих програм- мах, которые вы будете писать. Здесь важно понимать, что собой представляет каждая ошибка: относится ли она к общим ошибкам или вызвана непониманием. Это улучшит ваши возможности по разработке кода без ошибок. Кроме то- го, всегда лучше писать программу без ошибок, чем уметь быстро потом их исправлять. Общие ошибки ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В следующий примерах кратко охватываются различные типы оши- бок, которые могут встречаться в ваших программах. Скрытые эффекты ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Иногда вызов функции может приводить к неожиданным результа- там: char workbuf[20]; strcpy(workbuf, "all done\n"); convert("xyz"); print(workbuf); ... convert(char *p) { strcpy(workbuf, p); while (*p) ... } Здесь правильнее было бы использовать в функции свой собс- твенный рабочий буфер (workbuf). Предположения об инициализации данных ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Иногда вы предполагаете, что другая функция уже установила TDeb 3.0 #2-3 = 125 = для вас какие-то значения: char *workbuf; addworkstring(char *s) { strcpy(workbuf, s); } Надежнее будет записать эту подпрограмму, добавив оператор: if (workbuf == 0) workbuf = (char *)malloc(20); Не забывайте об очистке ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Этот тип ошибки может привести к тому, что ваша программа будет долго работать, но в конце-концов исчерпает динамически распределяемую область памяти и аварийно завершит работу: crunch_string(char *p) { char *word = (char*)malloc(strlen(p)); ctrcpy(work,p); ... return(p) } "Забор и столбы" ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Этот тип ошибок аналогичен следующему. Сколько столбов пона- добиться, чтобы построить 100-метровую изгородь,если столбы нужно ставить через каждые 10 метров? Напрашивается ответ 10, но он не- верен, так как в расчет принимается последний столб в конце забо- ра. Приведем простой пример из программирования на Си: for (n = 1; n < 10; n++) { ... /* выполняется только 9 раз */ } Здесь ясно видны числа 1 и 10, и вы можете подумать, что цикл будет выполняться от 1 до 10. Чтобы это действительно было так, нужно вместо < указать <=. Ошибки, специфические для языка Си ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В "Руководстве пользователя" по Си и С++ есть раздел о не- достатках программирования на Си. Однако лучше всего изучать эту TDeb 3.0 #2-3 = 126 = тему во время отладки. Компиляторы Borland Си и Borland C++ прекрасно подходит для того, чтобы находить многие из специфических для языка Си ошибок, о которых другие компиляторы вам даже не сообщают. "Включив" в компиляторе все предупреждающие сообщения, которые он может гене- рировать, вы сэкономите время, необходимое для отладки программы. (О том, как задавать уровень предупреждений, рассказывается в "Руководстве пользователя по Borland C++".) Далее мы приведем далеко не полный перечень возможных ошибок при использовании языка Си. Для некоторых из них Borland Си и Borland C++ генерирует предупреждающие сообщения. Не забудьте найти причину вывода всех предупреждающих сообщений, поскольку они могут быть вызваны возможной допущенной вами ошибкой. Использование неинициализированных локальных переменных ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В языке Си динамические локальные переменные, описанные внутри функции, будут иметь неопределенное значение, пока вы что- нибудь в них не загрузите. Например: do_ten_times() { int n; while (n < 10) { ... n++; } } Данная функция будет выполнять цикл while неопределенное чис- ло раз, так как перед использованием в качестве счетчика n не инициализируется значением 0. Не следует путать = и == ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В выражениях язык Си позволяет использовать как присваивание (=), так и проверку на равенство (==). Например: if (x = y) { ... } При этом y будет ошибочно загружено в x, а оператор выпол- нится, если значение y не равно 0. Вероятно, вы предполагали на- писать следующее: if (x == y) ... TDeb 3.0 #2-3 = 127 = Не следует путать старшинство операций ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В языке Си так много операций, что иногда легко спутать, ка- кая из них применяется первой, когда выражение содержит несколько операций. Одна из наиболее общих ошибок состоит в неправильном выполнении комбинации операции сдвига и операции сложения или вы- читания. Например: x = 3 << 1 + 1 Если << указывается перед +, то при вычислении этого опера- тора будет получено значение 12, а не 7, как можно было бы ожи- дать. Неверные арифметические действия с указателями ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Когда вы освоитесь с указателями и будет использовать их для работы с массивами, будьте внимательны при сложении и вычитании указателей. Например: int *intp; intp += sizeof(int); не будет работать так, как вы задумали (предполагая увеличить intp для ссылки на следующий элемент массива). Фактически, intp продвигается на два элемента массива. При сложении или при вычи- тании из указателя Си принимает во внимание размер элемента, на который ссылается указатель, поэтому все, что нужно сделать для продвижения указателя на следующий элемент массива - это опера- ция: intp++ Не забывайте о расширении по знаку ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Будьте аккуратны при присваивании целых чисел различного размера: int i = OXFFFE; long l; l = i; if (l & OX800000000) { ... /* это будет выполнено */ } Один из моментов в Си, который может привести к неприятнос- тям, состоит в том, что вы не знаете о последствиях. Язык Си поз- воляет свободно использовать присваивание одной целочисленной скалярной величины (char, int и т.д.) другой, знак (положительный TDeb 3.0 #2-3 = 128 = или отрицательный) сохраняется в переменной большего размера, причем бит знака (старший бит) распространяется на всю старшую часть большего скалярного значения. Например, значение типа int - 2 (Oxfffe) становится значением типа long -2 (oxfffffffe). TDeb 3.0 #2-3 = 129 = Помните об усечении ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Данный пример противоположен примеру предыдущего раздела: int i = 1; long l = OX10000; l = i; if (i > 0) { ... /* это не будет выполнено */ } Здесь присваивание i значения 1 приводит к усечению старших 16 бит 1, при этом в i остается значение 0. Использование точки с запятой ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Следующий фрагмент программы на первый взгляд выглядит прек- расно: for (x = 0; x < 10; x++); { ... /* будет выполнено 1 раз */ } Почему фрагмент в фигурных скобках будет выполнен только 1 раз? При ближайшем рассмотрении оказывается, что в конце выраже- ния for содержится точка с запятой (;). Это труднообнаруживаемая ошибка приводит к тому, что цикл выполниться 10 раз, не реализуя никаких действий. Последующий блок выполниться только 1 раз. Это неприятная ошибка, так как ее нельзя обнаружить с помощью обычных методов проверки и идентификации блоков программы. Макрокоманды с побочными эффектами ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Следующая проблема может заставить вас никогда не использо- вать макрокоманды #define: #define toupper(c) 'a'<= (c)&&(c)<='z' ? (c)-'a'-'A': (c) char c, *p; c = toupper(*p++); Здесь p увеличивается 2 или 3 раза, в зависимости от регист- ра символа (строчная или прописная буква). Такую ошибку очень трудно найти, так как побочный эффект скрыт внутри макроопределе- ния. Повторение имен локальных динамических переменных ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД TDeb 3.0 #2-3 = 130 = Следующую ошибку также трудно обнаружить: myfunc() { int n; for (n=5; n >= 0; n--) { int n = 10; ... if (n == 0) { ... /* никогда не будет выполняться */ } } } } Здесь имя динамической локальной переменной повторно исполь- зуется во внутреннем блоке, скрывая доступ к переменной внешнего блока. При таком повторном использовании имен переменных нужно соблюдать аккуратность. Сделать такую ошибку гораздо легче, чем может вам показаться, так как большинство программистов использу- ют в качестве имени счетчика ограниченный набор имен (i, n и т.д.). Неправильное использование динамических локальных переменных ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Рассмотрим пример функции: int *divide_by_3(int n) { int i; i = n / 3; return(&i); } Смысл данной функции состоит в возврате указателя на резуль- тат. Ошибка состоит в том, что к тому моменту, когда функция возвращает управление, динамическая локальная переменная стано- вится недействительной и будет вероятно заполнена другими данными в стеке. Функция возвращает неопределенное значение ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Если вы не завершаете функцию ключевым словом return, за ко- торым следует выражение, то будет возвращаться неопределенное значение. Например: char *first_capital_letter(char *p) TDeb 3.0 #2-3 = 131 = { while (*p) { if ('A' <= *p && *p <= 'Z) return(p); p++; } } Если в строке не содержится буква в верхнем регистре, то возвращается случайное значение ("мусор"). В качестве последней строки данной функции нужно использовать оператор return(0). Неправильное использование ключевого слова break ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Ключевое слово break выполняет выход только из одного уровня операторов do, for, switch или while: for (...) { while (...) { if (...) break; /* хотим выйти из цикла */ } } Здесь break выполняет выход только из цикла while. Это один из немногих случаев, когда предпочтительнее использовать опера- тор goto. Код, не приводящий к результату ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Иногда может встречаться прекрасно компилируемый код, кото- рый не приводит ни к какому результату: a + b; Правильным вариантом этой строки будет: a += b TDeb 3.0 #2-3 = 132 = Ошибки, специфические для Паскаля ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Поскольку в Паскале имеются средства, обеспечивающие строгую проверку типов и проверку ошибок, то этот язык мало способствует специфическим для него ошибкам. Однако, поскольку Турбо Паскаль предоставляет вам возможность "выключать" проверку ошибок, вы мо- жете внести ошибки, которые в противном случае не возникли бы. Между тем даже в Паскале есть способы этого избежать. Инициализированные переменные ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо Паскаль не инициализирует переменные автоматически. Вы должны сделать это сами с помощью операторов присваивания или описав такие переменные в виде типизованных констант. Рассмотрим следующую программу: program Test; var I,J,Count : integer; begin for I := 1 to Count do begin J := I*J; Writeln(I:2,' ',J:4) end end Здесь Count будет иметь какое-то случайное значение, содер- жащееся в занимаемой этой переменной ячейке памяти, поэтому вы не сможете определить, сколько раз будет выполнен данный цикл. Кроме того, переменные, описанные внутри процедуры или функции, будут создаваться каждый раз при входе в эту подпрограмму и уничтожать- ся при выходе из нее. Поэтому нельзя полагать, что эти переменные в промежутке между вызовами подпрограммы сохраняют свое значение. Неправильная работа с указателями ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Этот общий тип ошибок встречается при работе с указателями. Во-первых, как уже упоминалось ранее, не следует использовать их до того, как им будет присвоено значение (nil (пустое) или какое- либо другое). Как и все другие переменные или структуры данных, указатель не инициализируется автоматически при его описании. Ему нужно явным образом присвоить начальное значение (передав его в качестве параметра процедуре New или возможно быстрее присвоив ему значение nil). Во-вторых, не ссылайтесь на пустой указатель, то есть не пы- тайтесь обратиться к данным или структуре, на которые он указыва- ет, если указатель имеет значение nil. Например, предположим, что у вас имеется линейный связанный список записей, и вы хотите вы- полнить в нем поиск записи с заданным значением. Ваша программа TDeb 3.0 #2-3 = 133 = может выглядеть следующим образом: function FindNode(Head : NodePtr, Val : integer); var Temp : NodePtr; begin Temp := Head; while (Temp^.Key <> Val) and (Tamp <> nil) do Temp := Temp^.Next FindNode := Temp end { FindNode } Если Val не равно полю Key в каком-либо из узлов связанного списка, то эта программа, когда Temp имеет значение nil, будет пытаться вычислить Temp^.Key, что приведет к непредсказуемому по- ведению. Каково же здесь решение? Нужно записать выражение следу- ющим образом: while (Temp <> nil) and (Temp^.Key <> Val) и разрешить вычисление булевских выражений по короткой схеме (с помощью директивы Турбо Паскаля {$B-} или команды OptionsіCompilerіBoolean (ПараметрыіКомпиляторіБулевские выраже- ния)). Таким образом, если Temp не равно nil, второе условие вы- числяться не будет. Наконец, не следует предполагать, что указатель устанавлива- ется в значение nil только потому, что вы передаете его процедуре Dispose или FreeMem. Указатель будет иметь при этом свое исходное значение, однако память, на которую он указывает, будет теперь освобождена, и может использоваться для другой динамической пере- менной После освобождения структуры данных указатель нужно явным образом установить в значение nil. Неправильное использование области действия ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Паскаль позволяет вам использовать большой уровень вложен- ности процедур и функций, и в каждой их этих процедур и функций могут содержаться ее собственные описания. Рассмотрим следующую программу: program Confused; var A,B :integer; procedure Swap(var A,B : integer); var T : integer; begin Writeln('2: A,B,T = ',A:3,B:3,' ',T); T := A; A := B; TDeb 3.0 #2-3 = 134 = B := T; Writeln('3: A,B,T =',A:3,B:3,' ',T); end { Swap } begin { тело основной программы Confused } A:= 10; B := 20; T := 3-; Writeln('1: A,B,T = ',A:3,B:3,' ',T); Swap(B,A); Writeln('4: A,B,T = ',A:3,B:3,' ',T); end. { Confused } Выводимая программой информация будет выглядеть примерно следующим образом: 1: A,B,T = 10 20 30 2: A,B,T = 20 10 22161 3: A,B,T = 10 20 20 4: A,B,T = 20 10 30 Все это вызвано тем, что у вас имеется две версии переменных A, B и T. В теле основной программы используются глобальные вер- сии, в процедуре Swap - локальные версии (ее формальные параметры A и B и локальная переменная T). И что еще более запутало ситуа- цию, мы обратились с вызовом Swap(B,A), что означает, что фор- мальный параметр A является на самом деле глобальной переменной B и наоборот. И, конечно, нет никакой связи между локальной и гло- бальной версией переменной T. Настоящей ошибки здесь нет, но проблемы могут возникнуть, когда вы будете считать, что модифицируете что-то, а на самом де- ле это не так. Например, переменная T в теле основной программы не изменяется, хотя вы можете предполагать, что это не так. Этот результат, обратный описанным ранее "скрытым эффектам". Если бы вы использовали следующее описание записи, все стало бы еще более запутанным: type RecType = record A,B : integer; end; var A,B : integer; Rec : RecType; В операторе with ссылка на A или B привела бы к ссылке на fields, а не к ссылке на variables. Неправильное использование точки с запятой ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Как и язык Си, Паскаль допускает использование "пустого" TDeb 3.0 #2-3 = 135 = оператора (оператора, состоящего только из точки с запятой). Раз- мещенная в неверном месте точка с запятой может вызвать различные проблемы. Рассмотрим следующую программу: program Test; var I,J : integer; begin for I := 1 to 20 do; begin J := I*I; Writeln(I:2,' ',J:4) end; Writeln('Выполнено!') end. Выводом этой программы будет не список из первых 20 целых чисел и их квадратов, а просто: 20 400 Выполнено! Это вызвано тем, что оператор for I := 1 to 20 заканчивается точкой с запятой. При этом 20 раз будет выполнен пустой оператор. После этого выполняется оператор в блоке begin...end и, наконец, оператор Writeln. Чтобы исправить эту ошибку, нужно просто устра- нить точку с запятой за ключевым словом do. Функция возвращает неопределенное значение ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Когда вы пишете функцию, нужно убедиться, что перед тем, как функция возвращает управление, ее имени присваивается некоторое значение. Рассмотрим следующий пример кода: const NLMax = 100; type NumList = array[1...NLMax] of integer; ... function FindMax(List : Numlist; Count : integer) : integer; var I,MAX : integer; begin Max := List[1]; for I := 2 to Count do if List[I] > Max then begin Max := List[I]; FindMax := Max end end; { FindMax } TDeb 3.0 #2-3 = 136 = Эта функция будет прекрасно работать, если максимальным зна- чением в List не является List[1]. В этом случае никогда не будет присвоено значение. Правильный вариант функции должен выглядеть следующим образом: begin Max := List[1]; for I := 2 to Count do if List[I] > Max then Max := List[I]; FindMax := Max end; { FindMax } Уменьшение значения переменных размером в байт или слово ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Будьте внимательны и не уменьшайте беззнаковое скалярное значение (размером в слово или байт) при проверке на >= 0. Следу- ющий фрагмент программы образует бесконечный цикл: var w : word; begin w:= 5; while w >= 0 do w := w - 1; end. После пятой итерации w равно 0. При следующем проходе оно будет уменьшено до значения 65535 (так как переменная размером в слово принимает значения в диапазоне от 0 до 65535), что также >= 0. В этих случаях следует использовать переменные не типа word или byte, а типа integer или longint. Игнорирование границ и особые случаи ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Заметим, что в обеих версиях функции FindMax в предыдущем разделе предполагалось, что Count >= 1. Однако в некоторых случа- ях значение Count может быть равно 0 (то есть список пуст). Если вы в такой ситуации вызовите функцию FindMax, она возвратит то, что оказалось в List[1]. Аналогично, если Count > NLMax, выполне- ние либо завершиться с ошибкой (если разрешена проверка границ), либо поиск максимального значения будет выполняться в ячейках па- мяти, не относящихся к List. Здесь можно предложить два решения. Одно из них состоит, ко- нечно, в том, чтобы никогда не вызывать функцию FindMax, если Count не находится в диапазоне 1..NLMax. Это не пустое замечание. В серьезном программном обеспечении всегда определяются требова- ния, которые нужно выполнять при вызове определенной программы, а затем обеспечивается удовлетворение этих требований при вызове. TDeb 3.0 #2-3 = 137 = Другое решение состоит в проверке значения Count и, если оно не находится в диапазоне 1..NLMax, возврате некоторого предопре- деленного значения. Например, вы можете переписать тело функции FindMax следующим образом: begin if (Count < 1) or (Count > NLMax) then Max := -32768 else begin Max := List[1]; for I := 2 to Count do if List[I] > Max then Max := List[I]; end; FindMax := Max end; { FindMax } Однако это приводит к следующему типу ошибок при работе на Паскале - ошибкам диапазона. Ошибки диапазона ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД По умолчанию в Турбо Паскале проверка диапазона выключена. При этом получается более быстрый и компактный код, но в тоже время при этом вы можете следует определенного типа ошибки, та- кие, как присваивание переменным значения, выходящего за их до- пустимый диапазон, или обращение к несуществующему элементу мас- сива (как показано в приведенном выше примере). Первый шаг при обнаружении таких ошибок состоит во включении в программу директивы компилятора {$R+}, которая задает проверку диапазона, компиляции программы и повторном ее запуске. Если вы знаете (или догадываетесь), где содержится ошибка, можно помес- тить указанную директиву перед данной частью программы, а после нее указать директиву {$R-}, разрешив, таким образом, проверку диапазона только в той части программы, где содержится ошибка. Одна из общих ошибок выхода за границы диапазона возникает при использовании для индексации массива цикла while или repeat. Предположим, например, что вы ищете элемент массива, содержащий определенное значение. Вы хотите остановиться после того, как найдете его, или при достижении конца массива. При нахождении элементе вы ходите возвратить его индекс, а в противном случае - 0. Ваш первый вариант может выглядеть так: function FindVal(List : NumList; Count,Val : integer) : integer; var I : integer; begin FindVal := 0; TDeb 3.0 #2-3 = 138 = I := 1; while (I <= Count) and (List[I] <> Val) do Inc(I); if I <= Count then FindVal := I end; { FindVal } Это прекрасно, но если Val не содержится в List и вы исполь- зуете обычное вычисление булевских выражений, здесь может возник- нуть ошибка этапа выполнения. Почему? Потому что когда последний раз проверка выполняется в начале цикла while I будет равно Count + 1. Если Count = NLMax, вы выйдете за пределы List. Ошибки, специфические для Ассемблера ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В каждом языке имеется свое множество ошибок, которые обычно очень легко сделать, но не всегда просто обнаружить. Не является исключением и язык Ассемблера. Мы рассмотрим некоторые типичные ошибки, которые допускаются при программировании на Ассемблере, и дадим рекомендации, как можно их избежать. Программист забывает о возврате в DOS ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В Паскале, Си и других языках программа завершается и возв- ращается в операционную систему DOS автоматически, когда нет больше выполняемого кода, даже если в программе отсутствует явная команда ее завершения. В языке Ассемблера это не так. Ассемблер выполняет только те действия, которые вы явно указываете. Когда вы запускаете программу, в которой отсутствует команда возврата в DOS, она просто продолжает работать до конца выполняемого кода программы и переходит в код, который находится в примыкающей па- мяти. TDeb 3.0 #2-3 = 139 = Программист забывает об инструкции RET ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Заметим, что правильный вызов подпрограммы состоит из вызова подпрограммы из другой части кода, выполнения подпрограммы и возврата из подпрограммы в вызывающую программу. Не забудьте включать в каждую подпрограмму инструкцию RET, по которой управ- ление будет передаваться в вызывающий код. При наборе программы эту директиву легко пропустить. В этом случае ее выполнение за- кончится ошибкой. Генерация неверного типа возврата ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Директива PROC действует двояко. Во-первых, она определяет имя, по которому будет вызываться процедура. Во-вторых, она уп- равляет типом (ближним или дальним) процедуры. Тип процедуры используется Турбо Ассемблером для определения того, какой тип вызовов нужно генерировать при вызове процедуры из того же исходного файла. Тип процедуры также используется для определения типа инструкции RET, которая выполняется, когда про- цедура возвращает управление в вызывающий код. Идея здесь очевидна. Инструкции RET в процедуре должны соот- ветствовать ее типу, не правда ли? И да и нет. Проблема состоит в том, что возможно и часто же- лательно группировать отдельные подпрограммы в единую процедуру; и поскольку эти подпрограммы не имеют соответствующей директивы PROC, их команды RET соответствуют типу общей процедуры, который не обязательно соответствует типу каждой отдельной подпрограммы. Неправильный порядок операндов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Многие программисты ошибаются и изменяют порядок операндов в инструкциях процессора 8086 на обратный. Это, вероятно, связано с тем, что строка: mov ax,bx которая означает "поместить AX в BX", читается слева направо, и многие создатели микропроцессоров строят соответствующим образом свои ассемблеры. Однако в языке Ассемблера процессора 8086 фирма Intel использовала другой подход, поэтому для нас эта строка оз- начает "поместить BX в AX", что иногда приводит к путанице. Программист забывает о стеке или резервирует маленький стек ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В большинстве случаев не выделять явно пространство для сте- ка, это все равно, что ходить по тонкому льду. Иногда программы, TDeb 3.0 #2-3 = 140 = в которых не выделяется пространство для стека, будут работать, поскольку может оказаться так, что назначенный по умолчанию стек попадет в неиспользуемую область памяти. Но нет никакой гарантии, что такие программы будут работать при любых обстоятельствах, поскольку нет гарантии, что для стека будет доступен по крайней мере один байт. В большинстве программ для резервирования прост- ранства для стека должна присутствовать директива .STACK, и для любой программы эта директива должна резервировать достаточное пространство, чтобы его хватило для максимальных потребностей в программе. Вызов подпрограммы, которая портит содержимое нужных регистров ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД При разработке программы на Ассемблере регистры удобно расс- матривать, как локальные переменные, выделенные для использования в процедуре, с которой вы в данный момент работаете. В частности, нередко подразумевают, что при обращении к другим процедурам ре- гистры остаются неизмененными. На самом деле это не всегда так. Регистры - это глобальные переменные, и каждая процедура может сохранить или уничтожить содержимое любого из регистров. Ошибки при использовании условных переходов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Использование в языке Ассемблера инструкций условных перехо- дов (JE, JNE, JC, JNC, JA, JB, JG и т.д) обеспечивает большую гибкость в программировании, но при этом также очень просто оши- биться, выбрав неверный переход. Кроме того, поскольку в языке Ассемблера анализ условия и переход требуют по крайней меру двух строк исходного кода (а сложных условных переходов нескольких строк), условные переходы в языке Ассемблера менее очевидны и больше способствуют ошибкам, чем соответствующие операторы Паска- ля и Си. Неверное понимание работы префикса REP ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команды обработки строк имеют одну необычную особенность: после их выполнения используемые ими указатели сдвигаются таким образом, что указывают на адрес, отличающийся на 1 байт (или 2 байта, если если длина команды равна одному слову) от последнего обработанного адреса. Это может привести к некоторой путанице при повторении команд обработки строк, особенно команд REP SCAS и REP CMPS. Нулевое содержимое CX и работа с целым сегментом ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Повторное выполнении любых команд обработки строк при ра- венстве нулю регистра CX не даст никакого результата. Это может быть удобно в том смысле, что нет необходимости проверять его на ноль перед повторным выполнением команд обработки строк. С другой TDeb 3.0 #2-3 = 141 = стороны, невозможно получить доступ к каждому байту в сегменте с помощью байтовых команд обработки строк. Неправильная установка флага направления ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД При выполнении команды обработки строк связанные с ней ука- затели (SI, DI или оба) получают положительное или отрицательное приращение. Это зависит от состояния флага направления. С помощью команды CLD флаг направления может быть сброшен в 0. В этом случае при выполнении команд обработки строк указатель получает положительное приращение (смещается в сторону старших адресов). С помощью команды STD флаг направления устанавливается в 1. В этом случае указатель получает отрицательное приращение (сдвигается в сторону младших адресов). После того, как флаг нап- равления был установлен в определенное состояние, он будет оста- ваться в нем до тех пор, пока не будет выполнена еще одна команда CLD или STD, или пока значения флагов не будут извлечены из стека с помощью команды POPF или IRET. С одной стороны, удобно иметь возможность устанавливать флаг направления в определенное состоя- ние только один раз, а затем выполнять серию команд, которые должны использовать заданное направление. С другой стороны, это может привести к появлению неустойчивых и труднообнаруживаемых ошибок, в результате которых команды обработки строк работают по- разному в зависимости от работы команд, которые были выполнены значительно раньше. Ошибки при повторении команд сравнения строк ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команда CMPS сравнивает содержимое двух областей памяти, а команда SCAS сравнивает содержимое накапливающего регистра с со- держимым области памяти. Когда перед одной из этих команд стоит префикс REPE, она выполняет сравнение, либо пока CX не становится равным нулю, либо пока не обнаружится, что операнды не равны. Когда перед командой стоит префикс REPNE, она выполняет сравне- ние, либо пока CX не становится равным нулю, либо пока не обнару- жится что операнды равны. К несчастью, легко перепутать, где ка- кой префикс нужно использовать. Ошибки при назначении сегмента строк ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Все строковые команды по умолчанию используют в качестве сегмента исходных данных (если он есть) сегмент DS, а в качестве сегмента результирующих данных (если он есть) сегмент ES. Легко забыть об этом и попытаться, скажем, выполнить команду STOSB над сегментом данных, поскольку все данные, обрабатываемые не строко- выми командами, обычно находятся именно в этом сегменте. Неправильное преобразование из байта в слово ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД TDeb 3.0 #2-3 = 142 = В общем случае, для команд обработки строк желательно ис- пользовать максимально возможный размер данных (обычно слово, а для процессора 80386 - двойное слово), поскольку с данными боль- шего размера эти команды обычно работают быстрее. Однако здесь имеются две ловушки. Во-первых, преобразование из количества байт в количество слов с помощью простой команды: shr cx,l приведет к потере байта, если CX имеет нечетное значение, пос- кольку младший значащий бит будет сдвинут за пределы слова. Во-вторых, следует помнить, что команда SHR делит количество байт на два. Использование, скажем, команды STOSW с количеством байт, а не слов, может уничтожить другие данные и вызвать самые разнообразные ошибки. Использование нескольких префиксов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команды обработки строк с несколькими префиксами работают ненадежно, и их следует по возможности избегать. Необязательные операнды в командах обработки строк ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Необязательные операнды в командах обработки строк использу- ются только для задания размера данных и изменения сегмента и не гарантируют фактический доступ к данной области памяти. Уничтожение содержимого регистра при умножении ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Умножение (8 на 8 бит, 16 на 16 бит, либо 32 на 32 бита) всегда уничтожает содержимое как минимум одного регистра, не яв- ляющегося накапливающим регистром, который используется в качест- ве исходного операнда. TDeb 3.0 #2-3 = 143 = Ошибки, связанные с изменением содержимого регистров ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Команды обработки строк, такие как MOVS, STOS, LODS, CMPS и SCAS, могут влиять на состояние некоторых флагов и содержимое трех регистров при выполнении единственной команды. При использо- вании команд обработки строк следует помнить, что содержимое од- ного из регистров SI или DI (или обоих сразу) получает положи- тельное или отрицательное приращение (в зависимости от состояния флага направления) при каждом выполнении команды обработки строк. Содержимое регистра CX также получает отрицательное приращение как минимум один раз и, возможно, уменьшается до нуля при каждом использовании команды обработки строк с префиксом REP. Изменение состояния флага переноса ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В то время как одни команды неожиданно для программиста вли- яют на состояние регистров и флагов, другие команды не влияют да- же на те флаги, состояние которых было бы желательно изменить. Программист долго не использует флаги ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Состояние флагов сохраняется до тех пор, пока не будет вы- полнена следующая команда, которая его изменяет, что обычно про- исходит достаточно быстро. Поэтому рекомендуется после установки флагов выполнять действия над ними как можно быстрее, чтобы избе- жать самых разнообразных ошибок, связанных с неверной установкой флагов. Смешение операндов в памяти и непосредственных операндов ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Программа на языке Ассемблера может обращаться либо к смеще- нию области памяти, в которой хранится переменная, либо к значе- нию этой переменной. К сожалению, в языке Ассемблера нет ни инту- итивных, ни строгих способов, позволяющих различить эти два вида обращений, и в результате программисты часто путают обращения к смещению и обращения к значению. Ошибки, связанные с возвратом в начало сегмента ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Один из самых сложных моментов в программировании для мик- ропроцессора 8086 состоит в том, что к памяти нельзя обращаться как к одному большому массиву байт. Вместо этого память делится на части (сегменты) размером 64К (килобайт), и доступ к ним осу- ществляется через сегментные регистры. Сегментация памяти может вызвать труднообнаруживаемые ошибки, поскольку если программа пы- тается обратиться к адресу, который находится за границами сег- мента, в действительности вместо этого происходит возврат в нача- ло того же сегмента. TDeb 3.0 #2-3 = 144 = Сохранение содержимого регистров при обработке прерываний ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Каждый обработчик прерываний должен обязательно сохранять содержимое всех регистров. Хотя и допускается сохранять содержи- мое только тех регистров, которое изменяется данным обработчиком прерываний, для надежности работы все же рекомендуется заносить содержимое всех регистров в стек при входе в обработчик прерыва- ний и извлекать его из стека при выходе. Игнорирование групп в таблицах операндов и данных ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Использование сегментных групп позволяет программисту логи- чески разбивать данные на несколько областей, исключая при этом необходимость загружать сегментный регистр каждый раз, когда не- обходимо перейти от одной из таких логических областей данных к другой. К сожалению, тот способ, который используется для обработки сегментных групп в макроассемблере фирмы Microsoft (MASM), может вызвать некоторые проблемы, и пока не появился язык Турбо Ассемб- лер, сегментные группы доставляли программистам много неприятнос- тей. И хотя этих неприятностей практически невозможно было избе- жать, сегментные группы были нужны для связи ассемблерного кода с языками высокого уровня, такими как Си. В режиме Quirks языка MASM Турбо Ассемблер эмулирует MASM, и это означает, что в этом режиме он имеет те же проблемы, что и MASM.Если вы не собираетесь использовать режим Quirks языка MASM, можете больше ничего о нем не читать, однако если вы планируете работать с этим режимом, вам следует обратиться за дополнительной информацией к "Руководству пользователя по Турбо Ассемблеру". TDeb 3.0 #2-3 = 145 = Проверка ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Создание программы с допустимыми входными данными составляет только часть функций проверки. В следующих разделах обсуждаются некоторые важные случаи проверки, которым должны подвергаться каждая программа, прежде чем можно будет сделать вывод о ее пра- вильной работе. Проверка граничных условий и случаи ограничения ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Если вы считаете, что подпрограмма должна работать с данны- ми, принимающими значение в определенном диапазоне, вы должны подвергнуть эту подпрограмму проверке с данными, принимающим раз- личные значение в этом диапазоне. Например, если в вас имеется подпрограмма, выводящая на экран список длиной от 1 до 20 элемен- тов, вы должны убедиться, что она ведет себя правильно и в том случае, когда в списке имеется ровно 1 элемент, и в том случае, когда в списке 20 элементов (здесь могут скрываться различные ошибки, в частности, ошибка типа "столбы и забор", описанная ра- нее). Ввод ошибочных данных ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Когда вы убедитесь, что программа работает во всем диапазоне допустимых данных, следует убедиться, что она ведет себя коррект- но, когда вы задаете недопустимые входные данные. Например, убе- дившись, что предыдущая программа воспринимает значения в диапа- зоне от 1 до 20, нужно также убедиться, что 0 или 21 значение ей отвергаются. Отсутствие входных данных ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Этот момент при проверке и создании программы часто упуска- ют. Если вы пишете программу, которая правильно себя ведет при отсутствии входных данных, работа с ней значительно упростится. Отладка, как часть процесса создание программы ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Когда вы начинаете разработку программы, можно заранее зап- ланировать этап отладки. Необходимо установить, в какой степени различные части вашей программы должны выполнять проверку на до- пустимые входные и выходные данные. При большом объеме проверок вы получите в результате очень гибкую программу, которая часто будет сообщать вам об ошибочной ситуации, но продолжать работать после выполнения некоторых дейс- твий по восстановлению. Однако при этом объем программы возрастет и работать она будет медленнее. Такой тип программ довольно легко TDeb 3.0 #2-3 = 146 = отлаживать, поскольку до возникновения опасной ситуации подпрог- раммы сами сообщают вам о недопустимых входных данных. Можно также реализовать программу, в которой выполняется ма- ло проверок на допустимость входных и выходных данных или такие проверки совсем отсутствуют. Такая программа будет меньшей по объему и будет быстрее выполняться, но неверные входные данные или маленькая ошибка могут привести к аварийному завершению ее работы. Такой тип программ обычно труднее всего отлаживать, так как небольшая ошибка может проявиться при выполнении намного позднее. Это затрудняет выявление того места, где содержится ошибка. Большинство создаваемых программ сочетают в себе оба этих метода. Данные, воспринимаемые из внешних источников (например, вводимые пользователем или считываемые из файла на диске) подвер- гаются обычно более тщательной проверке, чем данные, передаваемые при вызове от одной подпрограммы к другой. TDeb 3.0 #2-3 = 147 = Пример сеанса отладки ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В примере сеанса отладки используются те методы, о которых мы рассказывали в предыдущих разделах. Отлаживаемая программа представляет собой вариант демонстрационной программы, использо- ванной в Главе 3 (BCDEMO.C или TPDEMO.PAS), только в нее предна- меренно внесены некоторые ошибки. Убедитесь, что в вашем текущем каталоге содержатся два фай- ла, необходимые для демонстрации отладки. Если вы отлаживаете программу на Турбо Паскале, вам понадобятся файлы TPDEMOB.PAS и TPDEMOB.EXE. Если вы работаете на языке Си, вам потребуются файлы BCDEMOB.C и BCDEMOB.EXE. (Буква B в конце имен файлов, означает, что в эту версию внесена ошибка.) Сеанс отладки программы на языке Си ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В данном разделе в качестве примера используется программа на языке Си. Если вы программируете на Паскале, см. ниже пример сеанса отладки с использованием программы Турбо Паскаля. Поиск ошибок ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД До того, как начать сеанс отладки, давайте запустим демонс- трационную программу с ошибкой и посмотрим, что она делает непра- вильно. Для запуска программы наберите: BCDEMOB Вам выведется подсказка для ввода строк текста. Введите две строки текста: one two three four five six Последняя пустая строка завершает ваш ввод. После этого программа BCDEMOB выводит результаты анализа введенных вами строк: Arguments: (1) Enter a line (empty line to end): one two three (2) Enter a line (empty line to end): fou five six Enter a line (empty line to end): Total number of letters = 7 (3) Total number of lines = 6 (4) Total word count = 2 (5) Average number of words per line = 0.3333333 (6) 'E' orrurs 1 times, 0 times at start of a word (7) 'F' occurs 1 times, 1 times at start of a word 'N' occurs 1 times, 0 times at start of a word TDeb 3.0 #2-3 = 148 = 'O' occurs 2 times, 1 times at start of a word 'R' occurs 1 times, 0 times at start of a word 'U' occurs 1 times, 0 times at start of a word There is one word 3 characters long (8) There is one word 4 characters long (9) 1 - аргументы; 2 - введите строку (пустая строка завершает ввод); 3 - общее число букв; 4 - общее число строк; 5 - общее число слов; 6 - среднее число слов на строке; 7 - 'E' встречается 1 раз, 0 раз в начале слова; 8 - имеется одно слово длиной в три символа; 9 - имеется одно слово длиной в 4 символа. Заметим, что в общем числе слов и букв имеется ошибка. Позд- нее окажется, что таблицы частот букв и слов основываются на оши- бочном значении счетчика букв и слов. Такая ситуация, когда в программе сразу несколько неверных мест, довольно типична. Это часто встречается на начальном этапе отладки. Разработка плана действий ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Первая задача состоит в том, чтобы решить, с какой ошибкой нужно разобраться в первую очередь. Хорошим правилом здесь явля- ется следующее правило: начинайте с ошибки, которая произошла "первой". В данной программе каждая вводимая строка разбивается на слова, после чего анализируется, наконец, когда будут введены все строки выводятся таблицы. Так как счетчики букв и слов, как и таблицы, неверны, можно предположить, что что-то делается неверно при начальной разбивке и подсчете. Теперь, после того, как вы немного обдумали проблему и наме- тили в общих чертах пути решения, пора начать отладку. Здесь стратегия будет состоять в том, чтобы проверить подпрограмму makeintowords и посмотреть, правильно ли она разбивает строку на завершающиеся нулевым символом слова, а затем посмотреть, пра- вильно ли подпрограмма analyzewords выполняет подсчет для анали- зируемой строки. Запуск Турбо отладчика ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Чтобы запустить пример сеанса отладки, наберите: TD BCDEMOB При этом Турбо отладчик загрузит демонстрационную программу, в которой содержится ошибка, и выведет начальный экран. Если вы хотите выйти из сеанса отладки и вернуться в DOS, нажмите клавиши Alt-X (это можно сделать в любой момент). Если вы безнадежно "заблудились", можно в любое время перезагрузить демонстрационную программу, нажав клавиши Ctrl-F2, и начать сначала (при этом точ- ки останова и выражения просмотра очищены не будут). TDeb 3.0 #2-3 = 149 = Поскольку первое, что нам нужно сделать - это проверка пра- вильности работы подпрограммы makeintowords, нужно выполнить программу до выполнения этой подпрограммы, а затем проверить все, что требуется. В этом случае можно использовать два подхода: вы можете выполнить шаг программы, выполнив makeintowords и убедив- шись,что она делает все правильно, или можно остановить программу после выполнения подпрограммы makeintowords, и проверить ее ре- зультаты. Убедиться в правильности работы подпрограммы makeintowords довольно просто. Для этого можно проверить формируемый ей выход- ной буфер. Давайте выберем второй подход. Чтобы сделать это, пе- реместите курсор на строку 42 и нажмите клавишу F4, выполнив программу до этой строки. Появится экран программы, после чего вам нужно ввести: one two three и нажать клавишу Enter. Проверка ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Итак, вы остановились на строке исходного кода после вызова функции makeintowords. Взгляните на содержимое буфера и посмотри- те, все ли правильно. Переместите курсор на одну строку вверх и поместите его под словом buffer. После этого нажмите Alt-F10 (для вывода окна Inspector (Проверка)). В окне проверки выведется со- держимое буфера buffer. Для просмотре элементов массива исполь- зуйте клавиши стрелок. Обратите внимание, что подпрограмма makeintowords действительно поместила в конце каждого слова нуле- вой символ (0). Это означает, что вам нужно просмотреть другую часть программы и проверить, правильно ли работает подпрограмма analyzewords. Для этого сначала удалите окно проверки, нажав кла- вишу Esc. Затем дважды нажмите клавишу F7 для выполнения програм- мы до начала работы analyzewords. Проверьте, что analyzewords была вызвана с корректным указа- телем в буфере. Для этого переместите курсор под bufp и нажмите Alt-F10 I. Вы увидите, что bufp действительно указывает на завер- шающуюся нулевым символом строку 'one'. Для удаления окна про- верки нажмите клавишу Esc. Поскольку ошибка возникает, очевидно, при подсчете символов и слов, давайте поместим точку останова в то место, где подсчитываются слова и символы. 1. Переместите курсор на строку 93 и нажмите клавишу F2, чтобы установить точку останова. 2. Переместитесь на строку 97 и установите другую точку ос- танова. 2. Наконец, установите точку останова на строке 99, благода- ря чему вы сможете увидеть значение счетчика символов, TDeb 3.0 #2-3 = 150 = возвращаемое данной функцией. Задание нескольких точек останова (как в данном примере) - это типичный способ, позволяющий узнать, все ли в программе дела- ется правильно, и проверить значения важных данных при каждом ос- танове программы на очередной точке останова. TDeb 3.0 #2-3 = 151 = Окно Watch ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Запустите программу, нажав клавишу F9. Программа остановит- ся, когда она достигнет точки останова на строке 93. Теперь можно просмотреть значение charcount (счетчик символов). Так как вы хо- тите проверять его каждый раз, когда встречается данная точка ос- танова, удобно использовать команду Watch (Просмотр), чтобы по- местить charcount в окно Watches (Просмотр). Переместите курсор под wordcounts (счетчик слов) и нажмите Alt-F10 W. В окне прос- мотра в нижней части экрана выводится текущее значение 0. Чтобы убедиться, что символ подсчитывается правильно, выполните одну строку, нажав клавишу F7. В окне просмотра (Watches) действитель- но выводится, что значение charcount = 1. Диалоговое окно Evaluate/Modify ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Снова запустите программу, нажав клавишу F9. Теперь вы вер- нулись на строку 93 для обработки другого символа. Снова дважды нажмите F9 для считывания последней буквы слова и завершающего нуля. Теперь charcount показывает корректное значение 3, а массив wordcounts будет обновлен для подсчета слов. Далее все отлично. Нажмите снова F9, чтобы начать обработку следующего слова в буфе- ре. Ага! Что-то не так. Вы ожидаете, что программа остановится снова на строке 93 (на точке останова) для обработки другого символа. Но она этого не делает. Она выполняется дальше и возвращается из функции. Единственным путем оказаться на строке 99 является истинное зна- чение проверяемого в цикле while значения. Это означает, что *bufp != 0 должно при вычислении получать ложное значение (false). Чтобы проверить это, переместитесь к строке 83 и отметьте все выражение *bufp != 0, поместив курсор под *, нажав клавишу Ins, и переместив курсор на завершающий 0 перед ). Теперь вычис- лите это выражение, открыв диалоговое окно DataіEvaluate/Modify (ДанныеіВычисление/Модификация) и нажав клавишу Enter, а затем выбрав переключатель Eval (Вычисление), чтобы отмеченное выраже- ние было воспринято. Значение в самом деле равно 0. Нажмите дваж- ды клавишу Esc для возврата в окно Module (Модуль). Эврика! ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Теперь, чтобы обнаружить ошибку, нужно сделать некий анали- тический скачок. Причина того, что bufp указывает на 0, состоит в том, что внутренний цикл while, начинающийся на строке 86, остав- ляет его в конце слова. Для продолжения на следующем слове вы должны увеличить bufp и переместить его с 0, который завершал TDeb 3.0 #2-3 = 152 = предыдущее слово. Для этого перед строкой 97 нужно добавить опе- ратор "bufp++". Вы можете перекомпилировать свою программу с этим оператором, однако Турбо отладчик позволяет вам "вставлять" выра- жения, используя для этого особый вид точек останова. Для этого нужно сначала перезагрузить программу, нажав кла- виши Ctrl-F2 (после этого вы можете начать проверку, сбросив сос- тояние программы). Теперь удалите все точки останова, которые бы- ли вами установлены в предыдущем сеансе отладки, для чего нажмите клавиши Alt-B D. Вернитесь к строке 97 и снова установите точку останова, нажав клавишу F2. Теперь откройте окно Breakpoints (Точки останова), нажав клавиши ALt-V B. Установите эту точку ос- танова, чтобы выполнять выражение bufp++ каждый раз, когда оно встречается. Для этого сделайте следующее: 1. Выберите команду ViewіBreakpoint (ОбзоріТочка останова). 2. Откройте окно Breakpoints (Точки останова), нажав клавиши Alt-F10. 3. Выберите команду Set Option (Установить параметры) для открытия диалогового окна Breakpoint Options (Параметры точки останова. 4. Установите селективный переключатель Action (Действие) в значение Execute (Выполнение). 5. Для вывода подсказки Action Expression (Выражение дейс- твия) нажмите клавишу Tab. 6. Введите bufp++ в ответ на подсказку. 7. Нажмите клавишу Esc, чтобы закрыть диалоговое окно, и клавиши Alt-F3 для возврата в окно Module (Модуль). Теперь запустите программу, нажав клавишу F9. Введите две входных строки: one two three four five six В ответ на третью подсказку нажмите клавишу Enter, а когда программа завершит работу, нажмите клавиши Alt-F5, чтобы увидеть ее экран (экран пользователя). Вы можете заметить, что ситуация существенно улучшилась. Об- щее число строк и слов выглядит неверным, но таблица правильна. Остановитесь на начале подпрограммы printstatistics и посмотрите, передается ли ей для вывода корректное значение. Для этого снача- ла перезагрузите программу (чтобы начать проверку заново), нажав клавиши Ctrl-F2. Затем перейдите к строке 104 и нажмите клавишу F4, чтобы выполнить программу до этой строки. Переместите курсор на аргумент nlines и нажмите Alt-F10 I, чтобы посмотреть на его TDeb 3.0 #2-3 = 153 = значение. Вы видите значение 6, хотя должно быть значение 2. Теперь вернитесь назад, туда, где эта подпрограмма вызыва- лась из основной программы, и посмотрите на значение nlines (чис- ло строк) там. Переместите курсор на строку 36 и поместите его под nlines. Нажмите клавиши Alt-F10 I для вывода его значения. В основной программе значение nlines равно 2, а это правильно. Если вы перейдете в них к строке 46, то увидите, что два аргумента - nwords и nlines - переставлены местами. Компилятор здесь не может определить, какой именно порядок вы имели в виду. Он использует то, что указано. Если вы исправите эти две ошибки, программа будет работать правильно. Если вы достаточно любопытны, то можете попробовать запустить исправленную версию программы BCDEMO.EXE. Сеанс отладки с использованием программы на Паскале ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Остальная часть данной главы посвящена описанию примера се- анса отладки программы, написанной на Турбо Паскале. Если вы ра- ботаете с Borland C++, то просмотрите предыдущие разделы, в кото- рых описывается сеанс отладки программы на языке Си. TDeb 3.0 #2-3 = 154 = Поиск ошибок ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Перед началом сеанса отладки давайте запустим демонстрацион- ную программу на Паскале, в которой содержится ошибка, и посмот- рим, что она делает неверно. Скомпилированная версия этой прог- раммы уже содержится на дистрибутивном диске. Для запуска программы наберите ее имя и передайте ей в ко- мандной строке три аргумента: TPDEMOB first second third Вам будет выведена подсказка для ввода строк текста. Введите две строки текста следующим образом: ABC DEF GHI abc def ghi Ввод завершает последняя пустая строка. После этого TPDEMOB выводит анализ введенного текста: 9 letter(s) in 3 words in 2 lines(s) (1) Average of 0.67 words per line (2) Word length: 1 2 3 4 5 6 7 8 9 10 (3) Frequency: 0 0 3 0 0 0 0 0 0 0 (4) Letter: M (5) Frequency: 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 (6) Word starts: 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 (7) Letter: Z Frequency: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Word starts: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Program name: C:\td\tpdemob.exe (8) Command line parameters: firs# secon% third (9) 1 - 9 букв в 3 словах; 2 - в среднем 0.67 слов на строке; 3 - длина слова; 4 - частота; 5 - буква; 6 - частота; 7 - начинает слово; 8 - имя программы; 9 - параметры командной строки. В этой выходной информации содержится пять различных ошибок: 1. Число слов сообщается неверно (3 вместо 6). 2. Число слов на строку неверно (0.67 вместо 3). 3. В заголовках второй и третьей таблиц выводится только по одной букве (вместо A..M, N..Z). 4. Вы ввели две строки, каждая из которых содержит буквы от TDeb 3.0 #2-3 = 155 = A до I, но в таблицах частоты букв показан только счетчик со значение 1 для этих букв. 5. Последний символ каждого параметра командной строки был потерян, и на экран выводится случайный символ (хотя па- раметры введены правильно). Выбор стратегии поиска ошибок ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Первая задача состоит в том, чтобы решить с какой из ошибок разбираться в первую очередь. Здесь можно предложить хорошее пра- вило: начинайте с той ошибки, которая появилась первой. В данной программе, после того, как данные инициализируются процедурой Init, ввод с клавиатуры считывается функцией GetLine, а затем об- рабатывается процедурой ProcessLine, пока пользователь не введет пустую строку. ProcessLine просматривает каждую строку ввода и обновляет глобальные счетчики. После этого процедурой ShowResults выводятся результаты. Наконец, полностью независимая подпрограм- ма - процедура ParmsOnHeap - строит связанный список параметров командной строки в динамически распределяемой области памяти, а затем выводит этот список в конце программы. Среднее число слов на строку вычисляется процедурой ShowResults на основе числа строки и слов. Так как значение счет- чика неверно, очевидно стоит взглянуть на процедуру ProcessLine и посмотреть, как изменяется значение переменной NumWords (число слов). Даже если значение NumWords верно, число 0.67 слов на строку не имеет смысла. Тогда ошибка возможно содержится в вычис- лениях процедуры ShowResults, на что также стоит обратить внима- ние. Заголовки для всех таблиц выводятся в результате обращения к процедуре ShowResults. Перед отслеживанием второй и третьей ошиб- ки следует подождать завершения работы основного цикла. Так как счетчики слов и букв содержат неверные значения, вероятно что-то упущено в процедуре ProcessLine (это относиться к первой и чет- вертой ошибке). Наконец, когда вы закончите исследовать части программы, от- носящиеся к работе со счетчиками слов и букв, для поиска и исп- равления последней (пятой) ошибки займитесь процедурой ParmsOnHeap. Теперь, после того, как обдумали проблему и наметили план ее решения, пришло время непосредственно начать отладку. Запуск Турбо отладчика ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Для того, чтобы начать отладку нашего примера, загрузите от- ладчик и укажите те же параметры командной строки: TDeb 3.0 #2-3 = 156 = TD TPDEMOB first second third Турбо отладчик загрузит версию демонстрационной программы, содержащую ошибку, и выведет начальный экран, меню и т.д. Если вы хотите выйти из сеанса отладки и вернуться в DOS, нажмите клавиши Alt-X (это можно сделать в любой момент). Если вы безнадежно "заблудились", можно в любое время перезагрузить демонстрационную программу, нажав клавиши Ctrl-F2, и начать сначала (при этом точ- ки останова и выражения просмотра очищены не будут). Для отладки таких подпрограмм, как ProcessLine, можно пред- ложить два подхода. Вы можете либо выполнять ее построчно (по ша- гам), убедившись, что она все делает правильно, либо остановить программу непосредственно после выполнения процедуры ProcessLine и посмотреть, верны ли результаты. Так как оба счетчика содержат неверные значения, лучше внимательно проанализировать процедуру ProcessLine и посмотреть, как обрабатываются символы. TDeb 3.0 #2-3 = 157 = Перемещение по программе ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Итак, вы собираетесь запустить программу и исследовать про- цедуру ProcessLine. Сделать это можно несколькими способами. Мож- но нажать четыре раза клавишу F8 (для пропуска вызовов процедур и функций), затем нажать один раз F7 (для трассировки вызова ProcessLine). Можно переместить курсор на строку 231, нажать F4 (команда Go to Cursor - Выполнение до курсора), а затем нажать один раз F7 для того, чтобы начать выполнение процедуры ProcessLine (трассировка вглубь). Можно привести и другие способы, однако используем следую- щий. Нажмите клавиши Alt-F9. При этом вам выведется подсказка (диалоговое окно) для ввода адреса кода, до которого вы хотите выполнить программу. Наберите ProcessLine и нажмите клавишу Enter. Программа будет выполнена до того места, когда управление получает процедура ProcessLine. Когда вам выведется подсказка для ввода строки, введите те же данные, что и раньше (то есть, ABC DEF GHI). Здесь есть несколько циклов. Во внешнем цикле просматривает- ся вся строка. Внутри данного цикла имеется цикл для пропуска символов, отличных от букв, а второй цикл обрабатывает слова и буквы. Переместите курсор к циклу while на строке 133 и нажмите клавишу F4 (Выполнение до курсора). Данный цикл будет выполняться, пока он не достигнет конца строки, или не будет найдена буква. Последнее условие проверяется с помощью вызова булевской функции IsLetter. Для трассировки функции IsLetter нажмите клавишу F7. IsLetter представляет собой вложенную функцию, которая воспринимает значение символа и возв- ращает значение True (истинное значение), если это буква, и зна- чение False в противном случае. При поверхностном анализе оказы- вается, что она проверяет только прописные буквы (верхний регистр). А она должна проверять символы в диапазоне 'A'...'Z' и 'a'...'z' или перед выполнением проверки преобразовывать символы в верхний регистр. Еще один ключ к поиску ошибки дает анализ обеих введенных строк. Вы ввели буквы верхнего и нижнего регистра от 'A' до 'I', но в общем итоге выведена только половина букв. Теперь вы уже знаете, почему. Давайте вернемся назад к строке, в которой вызывается IsLetter, с помощью еще одного метода перемещения: нажмите клави- ши Alt-F8, по которым программа будет выполнена до последнего оператора процедуры или функции. Так как вторая введенная строка содержит только буквы нижнего регистра, каждый символ обрабатыва- ется, как пробел, и пропускается. Это приводит к неверному значе- нию счетчиков слов и букв и выявляет причину ошибок 1 и 4. TDeb 3.0 #2-3 = 158 = Диалоговое окно Evaluate/Modify ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Кстати, существует еще один прекрасный способ выявить непра- вильное поведение IsLetter. Нажав клавиши Alt-D E, выведите диа- логовое окно Evaluate/Modify (Вычисление/Модификация) и введите следующее выражение: IsLetter('a') = IsLetter('A') И тот, и другой параметр (a и A) являются буквами, но ре- зультат вычисления False подтверждает, то они интерпретируются функцией IsLetter по-разному. (Окна вычисления и просмотра можно использовать для вычисления выражений, выполнения присваиваний, или, как в данном случае, вызовов процедур и функций. Более под- робно об этом рассказывается в Главе 6.) Проверка ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Итак, две ошибки выявлены, остались три. Ошибку 2 гораздо проще найти, чем предыдущие. Нажмите Alt-F8 для вызова из ProcessLine, затем переместите курсор к строке 234 и нажмите кла- вишу F4, чтобы выполнить программу до этой позиции курсора. Программа TPDEMOB выведет вам подсказку для ввода строки. Наберите abc def ghi и нажмите Enter. В ответ на повторный вывод подсказки просто нажмите клавишу Enter. Теперь нажмите клавишу F7 для трассировки процедуры ShowResults. Вспомните, что вы хотите определить, почему среднее число слов в строке имеет некорректное значение. В первой строке ShowResults вычисляется число строк на слово, а не число слов на строке. Ясно, что этот порядок следует изменить на обратный. Поскольку вы уже находитесь в данном месте, можно убедиться, что NumLines (число строк) и NumWords (число слов) имеют те зна- чения, которые вы ожидаете. NumLines должно быть равно 2 и, пос- кольку вы нашли ошибку в IsLetter, но не исправили ее, NumWords должно быть равно 3. Переместите курсор к NumLines и нажмите Alt- F10 I для проверки значения переменной. Окно Inspector (Проверка) показывает, что значение NumLines действительно равно 2. Теперь вы можете проанализировать NumWords. Нажмите клавишу Esc, чтобы закрыть окно Inspector, затем переместите курсор дальше на NumWords и снова нажмите Alt-F10 I (можно использовать также сок- ращение - клавиши Ctrl-I). NumWords содержит ожидаемое некоррект- ное значение 3, поэтому можно следовать дальше. Однако стоит ли торопиться? В этих вычислениях есть еще одна ошибка, отсутствующая в нашем списке. Перед выполнением деления значение второй переменной не проверяется на 0. Если вы запустите программу сначала и совсем не введете данные (нажав от ответ на TDeb 3.0 #2-3 = 159 = подсказку Enter), то программа аварийно завершит работу (даже ес- ли вы поменяете местами делимое и делитель). Чтобы убедиться в этом, нажмите Esc, чтобы закрыть окно Inspector, затем нажмите клавиши Alt-R P, чтобы завершить текущий сеанс отладки и F9, чтобы запустить программу сначала. В ответ на подсказку программу TPDEMOB нажмите клавишу Enter. Программа за- вершит работу и на экран выведется окно ошибки. Оператор следует изменить следующим образом: if NumLines <> 0 then AvgWords := NumWords / NumLines else AvgWords := 0; С ошибкой 2 покончено. Поскольку вы работаете с окном Inspector (Проверка), попробуйте использовать его для просмотра структуры данных. Переместите курсор выше к описанию LetterTable на строке 50. Поместите курсор на слово LetterTable и нажмите клавиши Alt-F10 I. Вы увидите, что это массив записей длиной в 26 элементов. Для просмотра каждого элемента массива используйте клавиши перемещения курсора, а для углубления в элемент массива - клавишу Enter. Это очень мощный способ проверки структур данных, он будет особенно удобен для последующего исследования связанного списка в процедуре HeapOnParms. Выражения просмотра ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Теперь давайте исследуем ошибку 3 в процедуре ShowResults (в выводе заголовка таблиц). Поскольку вы уже завершили программу, исследуя ошибку деления на 0, подготовьте ее для другого сеанса, нажав клавиши Alt-P (сброс программы). Затем нажмите клавиши Alt- F9, наберите showresults и нажмите Enter. После этого введите уже знакомые вам данные ABC DEF GHI и нажмите клавишу Enter. Наконец, наберите abc def ghi и дважды нажмите Enter. Теперь нужно остано- вить Турбо отладчик на ShowResults. В ShowResults для вывода таблиц букв используется вложенная процедура ShowLetterInfo Переметите курсор на строку 103, нажмите клавишу F4, затем F7 для перехода в ShowLetterInfo. Здесь имеется три цикла for. В первом цикле выводится заго- ловок таблицы, а во втором и третьем - значения частот. Исполь- зуйте клавишу F7 для перехода в первый цикл на строке 63. Позици- онируйте курсор на переменных FromLet и ToLet и используйте кла- виши Alt-F10 I для проверки их значений. Они выглядят верными (первое равно 'A', а второе - 'M'). Нажмите клавиши Alt-F5 для вывода экрана пользователя. Для возврата к окно Module (Модуль) используйте любую клавишу. При выполнении подобного цикла очень удобно использовать ок- TDeb 3.0 #2-3 = 160 = но Watch (Просмотр). Позиционируйте курсор на ch и нажмите клавиши Ctrl-W. Теперь для выполнения цикла по шагам используйте клавишу F7. Как и ожидалось, мы переходим к оператору Write на строке 64. Однако, если вы посмотрите на окно Watch (Просмотр), то увидите, что значение ch уже равно 'M' (уже выполнен весь цикл!). После ключевого слова do имеется лишняя точка с запятой, поэтому данный цикл 13 раз выполняется вхолостую. Когда управле- ние переходит к оператору Write на строке 64, то выводится теку- щее значение ch ('M'). Устранение лишней точки с запятой позволя- ет избавится от ошибки 3. Следующая ошибка ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Теперь настало время отследить ошибку при выводе параметров командной строки. Вспомним, что последний символ в каждом пара- метре командной строке содержал неверное значение ("мусор"). Воз- можно, неверен байт длины строки, или строковые данные портятся при последующих присваиваниях. Для выявления этого используйте окно Watch (Просмотр). Наж- мите клавиши Alt-F9, наберите parmonheap, затем нажмите Enter. Оператор for обработает в цикле все параметры командной строки, формируя связанный список и копируя каждую строку при ее поступ- лении в динамически распределяемую область памяти. Указатель Head указывает на начало списка, Tale - на последний узел в списке, а Temp используется, как временная память для выделения и инициали- зации нового узла. Так как строковые данные запорчены, нажмите клавиши Ctrl-F7 и добавьте в окно Watch следующее выражение: Tail^.Parm^ Это позволяет отслеживать строковые данные, хранящиеся в последнем узле списка. Конечно, до инициализации на строке 207 это значение будет содержать "мусор". Вместо того, чтобы выполнять программу по шагам, просто сле- дите за окном Watch в конце каждой итерации. Переместите курсор на строку 208 и нажмите клавишу F2, чтобы установить там точку останова. Теперь, чтобы выполнить программу до точки останова, нажмите клавишу F9. Если вы используете DOS версии 3.х, то в окне просмотра вы увидите полный маршрут доступа к TPDEMOB.EXE (при работе под управлением DOS 2.x вы увидите пустую строку, в этом случае просто нажмите клавишу F9 и работайте дальше). Строка дан- ных выглядит, как и требуется. Нажмите клавишу F9, чтобы выполнить цикл еще раз. Данные опять выглядят правильно. Теперь вы знаете, что строка копируется в динамически распределяемую область памяти правильно. Можно ис- пользовать окно Inspector (Проверка) и посмотреть, не повреждены ли еще данные. Переместите курсор к Head и нажмите клавиши Atl-F10 I. TDeb 3.0 #2-3 = 161 = Нажав клавишу Enter, посмотрите на значение, на которое ссы- лается Parm. Вы смотрите на первый элемент списка, и его строко- вые данные уже повреждены. Если вы нажмете клавишу Esc, стрелку вниз, а затем снова клавишу Enter, то вы откроете окно Inspector (Проверка) для второго узла (элемента) списка. Нажмите клавишу Enter, чтобы проверить строковые данные. Они не запорчены, факти- чески, на тот же узел ссылается указатель Tail. Очевидно, что-то не так с концом строковых данных. Следите за окном Watch, когда вы используете клавишу F7 для выполнения цикла. На строке 199 содержится вызов процедуры GetMem, перед этим вызовом Tail^.Parm^ равно первому символу. Не- посредственно после вызова GetMem последний символ в Tail^.Parm^ уничтожается. Что происходит? Для каждого параметра командной строки в цикле for сначала выделяется запись, затем строковые данные, за- тем следующая запись и т.д. При вызове GetMem на строке 198 долж- но выделяться достаточно памяти для строки, плюс байта длины, но, как можно заметить, к Length(s) не прибавляется 1. Хотя на строке 199 строка успешно копируется, для нее на самом деле выделено на 1 байт меньше, чем она использует. Таким образом, первый символ строки перекрывается первым байтом следующей записи, выделенной при обращении к процедуре New(Temp). Последний параметр остается незапорченным, так как на ним не следует другая ParmRec. Это все известные нам ошибки в программе. Возможно при ее выполнении вы найдете какие-то еще. Вы можете исправить эти ошиб- ки, а затем перекомпилировать программу (для удобства они отмеча- ются двумя звездочками (**)), или запустить TPDEMO.EXE - версию программу, о которой рассказывалось в Главе 3 и в которой ошибок нет. TDeb 3.0 #2-3 = 162 = Глава 15. Виртуальная отладка с использованием процессора 80386 ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Турбо отладчик позволяет вам полностью использовать произво- дительность систем, основанных на процессоре 80386. Виртуальная отладка позволяет отлаживаемым программам полностью использовать адресное пространство, превышающее 640К (как при отсутствии в па- мяти отладчика), поскольку Турбо отладчик загружается в расширен- ную память выше 1Мб.. Отладка выполняется так же, как при обычном использовании Турбо отладчика, только когда загружается драйвер TDH386, ваша программа загружается и выполняется с того же адреса, как и при обычном выполнении (без отладчика). Это может оказаться очень по- лезным как при отладке больших программ, так и при обнаружении ошибок, которые исчезают, если программа загружается в старшие адреса памяти. Виртуальная отладка также позволяет вам наблюдать за чтением и записью в произвольные ячейки памяти или ввода-вывода, не утра- чивая при этом (или почти не утрачивая) скорости выполнения. Это без дополнительной оплаты позволяет использовать все мощные средства аппаратной отладки. Если у вас имеется процессор 80286, то с помощью отладчика, работающего в защищенном режиме (TD286) вы можете получить в свое распоряжение больше памяти, чем при обычной работе с отладчиком. Более подробно об этом рассказывается в Главе 16. Аппаратные средства, необходимые для виртуальной отладки ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Чтобы можно было использовать виртуальный отладчик, в вашем компьютере должен применяться процессор 80386. Вы должны распола- гать также расширенной (extended) памятью объемом не менее 640К. Если вы используете расширенную память для псевдодисков, буферов и т.д., то может потребоваться создание специальных версий файлов CONFIG.SYS или AUTOEXEC.BAT, которые нужно будет использовать при виртуальной отладке. Установка драйвера устройства для виртуального отладчика ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Перед запуском виртуального отладчика нужно убедиться, что вашем файле CONFIG.SYS установлен драйвер устройства. Установить его можно, включив в данный файл следующую строку: DEVICE = TDH386.SYS Если драйвер TDH386.SYS содержится у вас не в корневом ката- логе, а в другом месте, то нужно указать маршрут доступа. Обычно виртуальный отладчик позволяет вам использовать до TDeb 3.0 #2-3 = 163 = 256 байт строк, задающих параметры операционной среды DOS. Если этого недостаточно, или вам не нужен такой объем и вы хотите сэ- кономить возможно больше памяти, используйте в файле CONFIG.SYS параметр -e, который задает число байт операционной среды. Напри- мер: DEVICE = TDH386.SYS -e2000 резервирует 2000 байт для переменных операционной среды DOS. Запуск виртуального отладчика ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Запускается виртуальный отладчик точно также, как обычный сеанс работы с Турбо отладчиком командой: TD386 [параметры] [программа [параметры_программы]] Другими словами, вместо TD указывается просто TD386. При этом будет выполняться поиск выполняемой программы Турбо отладчи- ка и загрузка ее в расширенную память. Если у вас есть другие программы или драйверы устройств, ис- пользующие расширенную память (псевдодиски, буферы и др.), вы должны указать TD386, сколько памяти занимают эти программы. Это можно сделать с помощью параметра командной строки -e, за которым указывается объем (в килобайтах) расширенной памяти, используемой другими программами, например: TD386 -e512 myprog Эта командная строка сообщает TD386, что вы хотите зарезер- вировать для других программ первые 512К расширенной памяти. Обычно, если в вашей системе поддерживается стандарт XMS, вовсе не обязательно сообщать TD386, сколько памяти нужно оста- вить для программ в расширенной памяти - программы уже передали эту информацию TD386. Параметр -e нужно использовать только с программами (такими, как VDISK), которые не взаимодействуют со стандартом XMS. Поскольку вы, вероятно, всегда резервируете один и тот же объем расширенной памяти, TD386 дает вам способ постоянного зада- ния объема резервируемой памяти. Чтобы сообщить, что вы хотите постоянно установить значение параметра -e в выполняемом файле TD386, используйте параметр -w. Вам будет выведена подсказка, в ответ на которую нужно ввес- ти имя выполняемой программы. Если вы работаете в DOS версии 3.0 или старше, в подсказке будет указываться маршрут доступа к ката- логу и имя файла, из которого запущен TD386. Вы можете использо- вать это имя, нажав клавишу Enter, или ввести имя нового выполня- емого файла. Файл с этим именем должен существовать и TDeb 3.0 #2-3 = 164 = представлять собой копию программы TD386. Если вы работаете под управлением DOS версии 2.х, вам при- дется указать полное имя выполняемой программы TD386 (с маршру- том). Перечислим параметры командной строки TD386.EXE: ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД -?, -h Выводит справочную информацию по TD386. -b Позволяет вам прерывать выполнение программы с помощью клавиш Ctrl-Break, даже когда запрещены прерывания. -e#### Задает, сколько килобайт расширенной памяти используют- ся другими программами или отлаживаемой вами программой (данный параметр указывать не требуется, если ваша систе- ма поддерживает стандарт XMS). -w Модифицирует TD386.EXE новым используемым по умолчанию значением -e или -f. -f#### Разрешает эмуляцию EMS с помощью страничного обмена (в расширенной памяти) и устанавливает сегмент границы стра- ницы в значение #### (шестнадцатиричное). Последние три цифры должны быть равны 000 (например, E000 или C000). Заметим, что данный параметр применяется только к вызовам EMS Турбо отладчика. Если вы не можете загрузить таблицу идентификаторов, попробуйте использовать параметр -f, чтобы вынудить TD386 заимствовать из расширенной памяти. Нет EMS: -fD000 EMS по адресу D000: -fE000 EMS по адресу E000: -fD000 -f- Запрещает эмуляцию EMS (отменяет действие предыдущего па- раметра командной строки). -w Модифицирует TD386.EXE новым используемым по умолчанию значением параметра -e или -f. Вы можете ввести имя ново- го выполняемого файла, который еще не существует. При этом TD386 создаст новый выполняемый файл. ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Заметим, что параметры TD386 должны указываться в командной строке перед другими параметрами Турбо отладчика или именем прог- раммы, например: TD386 -e1024 -fD000 -w резервирует 1024К расширенной памяти, разрешает эмуляцию EMS со страничной рамкой D000, и модифицирует TD386.EXE данными значени- ями. TDeb 3.0 #2-3 = 165 = Для вывода списка всех командных строк, которые можно ис- пользовать для TD386, наберите просто TD386 ? или TD386 -h и наж- мите клавишу Enter. Примечание: Если вы работаете на компьютере с процес- сором 386 и хотите прочитать параметры командной строки TD386.EXE, нужно перезагрузить TDH386.SYS. TDeb 3.0 #2-3 = 166 = Отличия обычной и виртуальной отладки ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД В основном при обычной отладке и при виртуальной отладке с использованием возможностей процессора 80386 все работает одина- ково. Различия состоят в следующем: 1. При использовании команды FileіDOS Shell (ФайліКомандный процессор операционной системы DOS) отлаживаемая програм- ма никогда не сбрасывается на диск. Это означает, что иногда вам может не хватить памяти для запуска других программ в ответ на подсказку DOS. 2. Ваша программа может использовать почти все инструкции процессора 80386, за исключением инструкций защищенного режима: CLTS, LMSW, LTR, LGDT, LIDT, LLDT. 3. Хотя при виртуальной отладке вы можете использовать все режимы расширенной адресации процессора 80386 и 32-раз- рядные регистры, вы не можете обращаться к памяти свыше 1 Мб. При попытке сделать это будет генерироваться прерыва- ние, и управление будет передано отладчику. 4. Нельзя использовать виртуальную отладку, если вы уже за- пустили программу или драйвер устройства, использующие виртуальный и защищенный режимы процессора 80386. Это та- кие программы, как: - операционная среда DesqView; - операционная среда Windows-386; - драйвер эмуляции EMS CEMM.SYS Compaq; - драйвер эмуляции EMS QEMM.SYS QuarterDeck; - 386^MAX. Если вы используете обычно одну из этих программ, вам придется остановить их или разгрузить перед использовани- ем TD386. 5. Если вы используете виртуальную отладку, TD386 может пе- рехватывать генерируемые вашей программой прерывания. Ес- ли происходит прерывание, программа останавливается и TD386 сообщает о том, что произошло прерывание. Выводимое сообщение описывает характер прерывания, а стрелка в об- ласти кода окно CPU (ЦП) или в окне Module (Модуль) отме- чает инструкцию, которая вызвала прерывание. 6. Непредвиденных прерываний возникать не должно. В случае их возникновения обратитесь к следующему разделу и про- верьте, упоминаются ли они там. Если нет, проконсульти- руйтесь с представителями фирмы Borland. Замечания относительно возможных проблем ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД TDeb 3.0 #2-3 = 167 = Если вы используете TDH386 и получаете сообщение "Not enouhg memory to load symbol table" ("Не хватает памяти для загрузки таблицы идентификаторов"), то вам нужно разрешить для TDH386 эмуляцию EMS. Например, чтобы установить для TDH386 EMS в сегмент 0D000h, используйте для запуска TDH386 следующую команду: TDH386 -FD000 Если вы используете HP Vestra и получаете при запуске TDH386 непредвиденное прерывание 06, нужно задать параметр в установке CMOS. По умолчанию серия Vestra использует в части HP-HILL инс- трукцию защищенного режима. Чтобы обойти это, свяжитесь с фирмой Hewlett Packard и узнайте, как обойти данную инструкцию. Если исключительная ситуация 06 возникает после того, как вы некоторое время поработаете в TDH386, то ваш исходный код будет, возможно, модифицирован. Обычно исключительная ситуация 06 гене- рируется процессором 80386, когда встречается недопустимый код операции. Типичной причиной этой ошибки является использование неинициализированных указателей. Исключительные ситуации 06, 13 и 0D могут возникать, если вы используете старый драйвер "мыши", сетевой драйвер или другой аппаратный драйвер. Если в TD386 вы получаете данные ошибки, по- пытайтесь удалить по очереди аппаратные драйверы, начиная с драй- вера "мыши", сетевого драйвера, и так далее, пока не идентифици- руете драйвер, приводящий к такой ситуации. Если для этого драй- вера имеются модификации, то посмотрите, устранит ли проблему их установка. Последняя возможная мера состоит в полном удалении драйвера. Если вы получаете во время загрузки TDH386 сообщения "Processor already in protected mode" ("Процессор уже в защищен- ном режиме"), это означает, что выполняется программа, использую- щая виртуальный режим процессора 80386 (например,QEMM). Использо- вать одновременно эти программы и TDH386 нельзя. Если вам необ- ходимо использовать данные подсистемы управления памятью, попы- тайтесь вместо TDH386 использовать TD286. Сообщения об ошибках TD386 ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД При невозможности начать работу TD386 генерирует одно из следующих сообщений и возвращает вас на уровень подсказки DOS. Перед тем, как запустить TD386, нужно исправить ситуацию. TD386 error: 80386 device driver missing or wrong version (нет драйвера 80386 или неправильная версия) Перед вызовом TD386 с помощью командной строки DOS нужно ус- TDeb 3.0 #2-3 = 168 = тановить в файле CONFIG.SYS драйвер TDH386.SYS. TD386 error: Can't enable the A20 adress line (не могу разрешить адресацию строки A20) TDH386 не может обратиться к памяти свыше 1Мб. Это может происходить в том случае, если вы работаете в системе, которая не полностью совместима с IBM. TD386 error: Can't find TD.EXE (невозможно найти TD.EXE) TD386 не может найти файл TD.EXE. TD386 error: Couldn't execute TD.EXE (невозможно выполнить TD.EXE) TD386 не может выполнить TD.EXE. TD386 error: Enviroment too long; use -e#### switch with TDH386.SYS (слишком длинная строка операционной среды, используйте TDH386.SYS с параметром -e####) Нужно изменить параметр -e, как было указано в предыдущих разделах. TD386 error: Not enough Extended Memory avaliable (объем доступной расширенной памяти недостаточен) TD386 превысил границы памяти. Нужно использовать машину с памятью большего объема или освободить память (уменьшив, напри- мер, объем псевдодиска). TD386 error: Wrong CPU type (not an 80386) (неправильный тип центрального процессора: не 80386) Вы работаете на системе, где используется процессор, отлич- ный от 80386. Следующие ошибки могут произойти, если вы модифицировали TD386 с помощью параметра -w: TD386 error: Cannot open program file (невозможно открыть файл программы) TD386 error: Cannot read program file (невозможно прочитать файл программы) TD386 error: Cannot write program file (невозможно записать файл программы) TD386 error: Program file corrupted or wrong version TDeb 3.0 #2-3 = 169 = (программный файл поврежден или неверна версия) Сообщения об ошибках TDH386.SYS ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Может возникнуть только две ошибки, связанных с драйвером TDH386.SYS: Wrong CPU type: TDH driver not installed (неверный тип ЦП: драйвер TDH не установлен) Invalid command line: TDH driver not installed (недопустимая командная строка: драйвер TDH не установлен) TDeb 3.0 #2-3 = 170 = Глава 16. Отладка в защищенном режиме с использованием TD386 ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Отладчик для защищенного режиме TD386 использует преимущест- ва процессора 80286 и позволяет освободить больше памяти для от- лаживаемых вами программ. TD386 помещает программу Турбо отладчи- ка в расширенную память выше 1Мбайта и оставляет в нижних 640К памяти сравнительно небольшой загрузчик. Это дает вам больше мес- та для программ, которые вы отлаживаете, и их таблиц идентифика- торов. Используйте в этом случае Турбо отладчик, как обычно. Единс- твенным отличием будет то, что вашей программа получит больший объем памяти. Замечание: Если вы работаете на компьютере с процессо- ром 80386 и еще не используете программу защищенного режима типа 386^MAX, то еще большие возможности и экономию памяти вам даст отладчик TD386. Более подробно об этом рассказыва- ется в Главе 15. Аппаратура, необходимая для использования отладчика TD286 ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Чтобы использовать отладчик защищенного режима TD286, вы должны иметь компьютер с процессором 80286 или старше и не менее 640К доступной расширенной памяти. Установка отладчика для защищенного режима ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Перед тем, как в первый раз использовать TD286, вы должны запустить программу конфигурации TD286INS. Это позволит TD286 оп- ределить некоторые характеристики аппаратуры, на которой вы рабо- таете. Для настройки конфигурации TD286 запустите программу TD286INS в ответ на подсказку DOS. Программа TD286INS после того, как она определит характерис- тики аппаратных средств, попросит вас нажать несколько раз клави- шу пробела. Если в какой-либо момент ваша система "зависнет" и не будет дальше работать, то перезагрузитесь и повторно запустите программу конфигурации. Программа конфигурации знает о том, что возникла проблема, и продолжает выполнять следующую фазу тестиро- вания. Когда программа TD286INS завершит выполнение, можно будет использовать TD286. TDeb 3.0 #2-3 = 171 = Запуск отладчика для защищенного режима ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Запустить отладчик для защищенного режима можно с помощью командной строки со следующим синтаксисом: TD286 [параметры] [программа [параметры программы]] Параметры TD286 совпадают с параметрами обычного отладчика. за исключением параметров -r, -rn, -rp, -rs, -sm, -w, -y, -ye. (TD286 не работает с оверлеями, удаленной отладкой и Windows). Отличия Турбо отладчика и отладчика для защищенного режима ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Есть несколько функций, которые вы можете выполнять в Турбо отладчике, но не можете использовать в отладчике TD286: - когда вы используете команду FileіDos Shell (ФайліКоманд- ный процессора DOS) для выполнения команды DOS, программа, которую вы отлаживаете, не сбрасывается на диск. Это озна- чает, что вам может не хватить памяти для выполнения прог- рамм в ответ на подсказку DOS. - вы не можете использовать отладчик TD286 для отладки прог- рамм, работающих в защищенном режиме, или использовать расширитель DOS, который приводит к конфликту с TD286. Отладка программ, использующих дополнительную память ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД По умолчанию TD286 будет использовать всю доступную расши- ренную память. Если вы отлаживаете программу, которая сама ис- пользует этот вид памяти (extended memory), то для использования TD286 нужно создать файл конфигурации CONFIG.286 в корневом ката- логе текущего дисковода. В этом файле должна быть строка: MEGS=# где # - это объем расширенной памяти, которую может использовать отладчик. Выполнение TD286 на разных машинах ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Отладчику TD286 известны аппаратные характеристики десятков машин. Когда вы запускаете TD286INS, и она сообщает "Machine already in file's database" (машина уже описана в файле базы дан- ных), то TD286 уже знает о вашем компьютере, и модификация не требуется. Если TD286INS выполнит свои проверки (тестирование), то ап- паратные характеристики вашей машины будут записаны в TD286, и TDeb 3.0 #2-3 = 172 = будет создан файл с расширением .DB. Этот файл следует послать фирме Borland или на одну из конференций Compuserve, благодаря чему следующие версии TD286 смогут автоматически поддерживать ха- рактеристика вашего компьютера. TD286 может хранить характерис- тики до 10 компьютеров, отличных от того, на котором он начал ра- ботать. |