ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
Часть 12 Глава 9. Выражения Выражения могут включать в себя идентификаторы вашей программы (то есть имена переменных и подпрограмм), а также константы и операции одного из поддерживаемых языков (Паскаля или Ассемблера). Турбо отладчик TDW может вычислять выражения и сообщать вам значение результата. Выражения можно также использовать для ссылки на элементы данных в памяти, значение которых вы хотите узнать. Выражение можно вводить в ответ на любую подсказку, в которой з апрашивается значение адреса памяти. (Заметим, что в различных языках выражения вычисляются по-разному.) Для вычисления значения введенного выражения можно использовать команду основного меню DataіEvaluate/Modify (ДанныеіВычисление/Модификация). Эту команду можно также использовать, как простейший калькулятор, а также для проверки значений объектов данных в программе. В данной главе мы расскажем вам о том, каким образом Турбо отладчик TDW определяет, какой язык нужно использовать для вычисления выражения, и как задать использование конкретного языка. Мы опишем элементы выражений, которые являются общими для всех языко в, такие, как номера исходных строк и доступ к регистрам процессора. Затем мы опишем компоненты, которые входят в выражение на любом языке, включая константы, переменные программы, строки и операции. Для каждого языка мы перечислим также поддерживаемые Т урбо отладчиком TDW операции и опишем синтаксис выражений. Полное описание выражений Паскаля или Ассемблера содержится в "Руководстве пользователя по Турбо Паскалю для Windows". Выбор языка для вычисления выражения Турбо отладчик TDW обычно определяет, какой язык нужно использовать для вычисления выражения, на основе расширения имени исходного файла в текущем модуле. Это тот модуль, в котором остановилась ваша программа. Этот выбор можно отменить с помощью команды OptionsіLanguage (ПараметрыіЯзык) и открытия диалогового окна Expression Language (Язык для выражений), в котором вы можете с помощью селективного переключателя выбрать один из поддерживаемых языков (Паскаль или Ассемблер). Если вы выберете значение Sour ce (Исходный), то выражения вычисляются в соответствии с языком исходного файла (если Турбо отладчик TDW не может определить этот язык, он использует правила языка встроенного Ассемблера). Обычно выбор языка предоставляют Турбо отладчику TDW. Иногда может оказаться полезным задать язык явным образом (например, при отладке модуля на Ассемблере, который вызывается из модулей на других языках). Явно задав язык для вычисления выражения, вы мож ете обращаться к данным так же, как в этом языке, даже если в текущем модуле используется другой язык. Иногда удобно интерпретировать выражения или переменные так, как будто они написаны на другом языке. Например, если вы отлаживаете программу на Паскале, правила языка Ассемблера предоставляют более простой способ изменения значения или байта в строке. Если первоначальный выбор языка при входе в TDW корректен, использование в дальнейшем соглашений другого языка не представляет трудностей. TDW будет сохранять информацию об исходном языке и использовать соответствующие преобразования и правила хранения д анных. Если язык не определяется однозначно, TDW использует правила языка Ассемблера. Даже если вы при запуске TDW преднамеренно выберите неверный язык, то можно получить некоторую информацию об исходном языке из таблицы идентификаторов и исходного файла. Однако в некоторых обстоятельствах можно запутать TDW, и он будет записывать данные некорректно. Адреса кода, адреса данных и номера строк Обычно, когда нужно получить доступ к переменной или имени подпрограммы в вашей программе, вы просто вводите ее имя. Однако можно также вводить указатель, при вычислении которого получается указатель на память, или задавать адреса кода в виде номеров исх одных строк, указывая перед номером строки символ # (например, # 123). В следующем разделе рассказывается, как можно обращаться к идентификаторам, находящимся вне текущей области действия. Конечно, с помощью обычного синтаксиса вида "сегмент:смещение" вы можете задать шестнадцатиричный адрес: ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Язык Формат Пример ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Паскаль $nnnn $1234:0010 Ассемблер nnnnh 1234h:0B234h ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Примечание: В Ассемблере шестнадцатиричные числа, начинающиеся с A - F, должны записываться с 0 в качестве первой цифры. Доступ к идентификаторам вне текущей области действия Область, в которой Турбо отладчик TDW ищет идентификатор, называется областью действия этого идентификатора. Доступ к идентификаторам, лежащим за пределами текущей области действия, представляет собой сложное понятие, глубоко разбираться в котором в боль шинсте случаев использования отладчика нет необходимости. Обычно Турбо отладчик TDW ищет входящий в выражение идентификатор точно так же, как это делает соответствующий компилятор. Например, компилятор Паскаля ищет его сначала в текущей процедуре или функции, затем во "внешней" подпрограмме (если активная облас ть действия вложена в другую), затем в секции реализации в текущем модуле (если текущая область действия находится в модуле), и, наконец, выполняет поиск глобального идентификатора. Если Турбо отладчик TDW не может найти идентификатор, используя данные методы, то он ищет его во всех других модулях, пытаясь найти соответствие среди статических идентификаторов. Это позволяет вам ссылаться на идентификаторы в других модулях, не указыва я явно имени модуля. Если вы хотите указать Турбо отладчику TDW, что идентификатор нужно искать в каком-то конкретном месте, то при указании имени идентификатора можно задать имя модуля, файл в модуле и подпрограмму. Вы можете получить доступ к любому идентификатору программ у, значение которого определено, даже к тем идентификаторам, которые являются частными для процедуры или функции и имена которых входят в конфликт с другими идентификаторами. Синтаксис переопределения области действия Независимо от используемого языка для переопределения области действия идентфикатора с данным имененем используется один и тот же метод. Для разделения компонентов области действия используется обычно символ #. Если это не будет двусмысленным для текущего языка, с этой целью можно также использовать точку (.), опустив начальный символ номера. Таким образом, для переопределения области действия используется следующий синтаксис (в квадратные скобки заключены необязательные элементы): [#модуль[#имя_файла]]#номер_строки[#номер_переменной] или [#модуль[#имя_файла]][#имя_функции]#имя_переменной Если вы не задаете модуль, то подразумевается текущий модуль. Приведем некоторые примеры допустимых выражений для идентификаторов с переопределеним области действия (каждой допустимой комбинации элементов, которые можно использовать для переопределения области действия соответствует один пример). В первых 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.) #mymodule#myvar2 (Переменная myvar2 доступна из модуля mymodule.) #mymodule#myfunc#myvar2 (Переменная myfunc доступна из подпрограммы myfunc в модуле mymodule.) #mymodule#file2#myvar2 (Переменная myvar2 доступна из файла file2, являющегося частью модуля mymodule.) #mymodule#file2#myfunc#myvar2 (Переменная myvar2 доступна из подпрограммы myfunc, определенной в файле file2, который входит в модуль mymodule.) Турбо отладчик TDW также поддерживает синтаксис переопределения модуля Паскаля: имя_модуля.имя_идентификатора Наконец, Турбо отладчик TDW позволяет вам переопределить область действия с помощью имени объекта, класса и метода (для объектно-ориентированных программ). Ниже приведены несколько примеров, которые не включают объекты и методы: AVar Переменная AVar доступна в текущей области действия. AProc Процедура AProc доступна в текущей области действия. AProc.AVar Локальная переменная AVar процедуры AProc доступна в текущей области действия. AProc.ANestedProc Процедура ANestedProc доступна в процедуре AProc, доступной в текущей области действия. AUnit.AProc.AVar Локальная переменная AVar доступна в процедуре AProc, которая доступна в модуле AUnit. AUnit.AProc.ANestedProc.AVar Локальная переменная AVar доступна в процедуре ANestedProc, которая доступна в процедуре AProc, которая, в свою очередь, доступна в модуле AUnit. TDW позволяет вам переопределить область действия путем использования имен объекта, класса или метода. Ниже приводятся несколько примеров, включающих объекты и методы: Instance Экземпляр Instance доступен в текущей области действия. Instance.AField Поле AFild доступно в экземпляре Instance, доступном в текущей области действия. AnObjectType.AMethod Метод AMethod доступен в типе объекта AnObjectType, доступном в текущей области действия. AnInstance.AMethod Метод AMetod доступен в экземпляре AnInstance, доступном в текущей области действия. AUnit.AInstance.AFild Поле AFild доступно в экземпляре AInstance, который доступен в модуле AUnit. AUnit.AnObjectType.AMethod Метод AMethod доступен в типе AnObjectType, который доступен в модуле AUnit. AUnit.AnObjectType.AMetod.ANestedProc.AVar Локальная переменная AVar доступна в процедуре ANestedProc, которая доступна в методе AMethod, который доступен в типе AnObjectType, который, в свою очередь, доступен в модуле AUnit. Вы можете вводить такие уточненные идентификаторы выражений в любом месте, где выражение допустимо (в том числе и в окнах просмотра и вычисления (Watch и Evaluate/Modify)), например, если вы изменяете выражение в окне проверки (Inspector) или используете локальное меню в окне Module (Модуль) для перехода (Goto) по адресу метода или процедуры в исходном коде. Неявная область действия при вычислении выражений Всякий раз, когда Турбо отладчик TDW вычисляет выражение, он должен определить без явного указания, где в программе находится область действия каждого идентификатора. Во многих языках это имеет существенное значение, так как в процедурах и функциях могут использоваться идентификаторы с теми же именами, что и глобальные идентификаторы. Турбо отладчик TDW должен знать, какой именно идентификатор вы имеете в виду. В качестве основы при принятии решении об области действия Турбо отладчик TDW обычно использует текущую позицию курсора. Например, вы можете задать область действия, которая будет использоваться при вычислении выражения, переместив курсор на ту или иную строку в окне Module (Модуль). Это означает, что при смещении курсора с текущей строки, где остановилась ваша программа, вы можете при вычислении выражения получить непредвиденные результаты. Если вы хотите убедиться, что выражения вычисляются в текущей области действия вашей программ ы, используйте команду локального меню окна Module Origin (Начало), чтобы вернуться к текущему адресу исходного кода. Задать область действия выражения можно также, перемещаясь в области Code (Код) окна CPU (Центральный процессор), устанавливая курсор на подпрограмму в окне Stack (Стек) или на имя подпрограммы в окне Variables (Переменные). Списки байт В некоторых командах от вас требуется ввести список байт. Это команды локального меню области Data (Данные) окна CPU (Центральный процессор) Search (Поиск) и Change (Изменение) или такие же команды локального меню окна File (Файл), в котором файл выводит ся в шестнадцатиричном виде. Список байт может представлять собой произвольную смесь скалярных (без плавающей точки) чисел и строк, в которых используется синтаксис текущего языка (его можно задать командой OptionsіLanguage (ПараметрыіЯзык)). И в строках, и в скалярных значениях исп ользуется тот же синтаксис, что и в выражениях. Скалярные значения преобразуются в соответствующую последовательность байт. Например, длинное целое (longint) значение Паскаля 123456 преобразуется в 4-байтовый шестнадцатиричный эквивалент 40 E2 01 00. ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Язык Список байт Шестнадцатиричные данные ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Паскаль 'ab'#4'c' 61 62 04 63 Ассемблер 1234"AB" 34 12 41 42 ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Выражения языка Паскаль Турбо отладчик TDW, за исключением конкатенации строк и операций над множествами, поддерживает синтаксис выражений Паскаля. Выражение представляет собой смесь операций, строк, переменных и констант. В следующих разделах описывается каждый из образующих в ыражение компонентов. Идентификаторы Паскаля Идентификаторы в Паскале представляют собой определенные пользователем имена элементов данных или подпрограмм вашей программы. Имя идентификатора Паскаля может начинаться с буквы (a - z, A - Z) или символа подчеркивания. Последующие символы в имени могут содержать цифры (от 0 до 9) и подчеркивания, а также буквы. Обычно идентификаторы подчиняются правилам области действия Паскаля, при этом "вложенные" локальные идентификаторы переопределяют другие идентификаторы в том же имени. Вы можете переопределить данную область действия, если хотите получить доступ к иденти фикаторам в других областях. Более подробно это описывается в разделе "Доступ к идентификаторам вне текущей области действия". Константы Паскаля и формат чисел Константы могут быть либо вещественными (с плавающей точкой), либо целыми. Отрицательные константы начинаются со знака минуса (-). Если число содержит десятичную точку или символ e, что обозначает экспоненту, то это вещественное число. Например: 123.4 456e34 123.45e-5 Константы целого типа являются десятичными, если они не начинаются со знака доллара ($), что означает шестнадцатиричную константу. Десятичные целые константы могут принимать значения в диапазоне от 2137483648 и 2147483647. Шестнадцатиричные константы дол жны лежать в диапазоне от $00000000 до $FFFFFFFF. Строки Паскаля Строка представляет собой просто группу символов, заключенных в одиночные кавычки, например: 'abc' Указав перед десятичным управляющим символом символ #, можно включить в строку управляющие символы, например: 'def'#7'xyz' Операции Паскаля и старшинство операций Турбо отладчик TDW поддерживает все операции, использующиеся в выражениях Паскаля. Унарные операции имеют старший и одинаковый приоритет. @ Получает адрес идентификатора. ^ Содержимое указателя. not Поразрядное дополнение. идентификатор_типа Приведение типа. + Унарный плюс (положительное значение). - Унарный минус (отрицательное значение). Бинарные операции имеют более низкий приоритет, чем унарные операции. Перечислим их в порядке убывания приоритета (операции на одной строке имеют равный приоритет): * \ 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) Можно также вызывать процедуры (но, конечно, не в выражениях). Когда вы вводите просто имя процедуры или функции, Турбо отладчик TDW выводит ее адрес и описание. Чтобы вызвать процедуру или функцию, которая не имеет параметров, укажите после имени функци и скобки, например: MyProc() Вызывает MyProc. MyProc Сообщает адрес MyProc и т.д. MyFunc=5 Сравнивает адрес MuFunc c 5. MyFunc()=5 Вызывает MyFunc и сравнивает возвращаемое значение с 5. Выражения Ассемблера Турбо отладчик TDW поддерживает полный синтаксис выражений Ассемблера. Выражение состоит из смеси операций, строк, переменных и констант. Каждый из этих компонентов описывается в следующем разделе. Идентификаторы Ассемблера Идентификаторы представляют собой определенные пользователем имена элементов данных и подпрограмм в вашей программе. Имя идентификатора Ассемблера начинается с буквы (a - z, A - Z) или одного из следующий символов: @, ?, _, $. Последующие символы в идент ификаторе могут содержать цифры (0 - 9) или любой из указанных символов. В качестве первого символа имени идентификатора (но не внутри имени) можно также использовать точку. Специальный идентификатор $ ссылается на текущий адрес программы, определяемый парой регистров CS:IP. Константы Ассемблера Турбо отладчик TDW обеспечивает работу с константами всех типов, которые используются в Ассемблере (byte, word, длинные, составные, с плавающей точкой, вещественные, с двойной и расширенной точностью). Константа с плавающей точкой содержит десятичную точ ку и может использовать научное десятичное представление. 1.234 4.5e+11 Если не используется одно из соглашений Ассемблера по переопределению основания, то целочисленные константы являются шестнадцатиричными. ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Формат Основание ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД цифрыH Шестнадцатиричное цифрыO Восьмеричное цифрыQ Восьмеричное цифрыD Десятичное цифрыB Двоичное ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Шестнадцатиричное число всегда должно начинаться с цифры (0 - 9). Если вы ходите начать число с одной из букв (A - F), то перед ним должен следовать 0. Операции Ассемблера Турбо отладчик TDW поддерживает большинтво операций, использующиеся в Ассемблере. Старшинство этих операций соответствует старшинству операций, принятому в Ассемблере: xxx PTR (BYTE PTR...) .(селектор элемента структуры) :(переопределение сегмента) OR XOR AND NOT EQ NE LT LE GT GE + - * / MOD SHR SHL Унарный -, Унарный + OFFSET SEG () [] Переменные можно изменять с помощью операции присваивания =. Например: a = [BYTE PTR DS:4] Управление форматом Когда вы указываете выражение, которое должно выводиться на экран, Турбо отладчик TDW выводит его в формате, основывающемся на типе данных, которые в нем используются. Турбо отладчик TDW игнорирует управление форматом, неверное для данного типа данных. Если вы хотите изменить используемый по умолчанию формат вывода данных на экран, поместите в конце выражения запятую и необязательный счетчик повторения, за которым указывается необязательная буква формата. Счетчик повторения нужно задавать только для ма ссивов. Символы, управляющие форматом вывода Ассемблера, описываются в следующей таблице: ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД Идентификатор Формат ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД c Символ или строка выводятся на экран в виде необработанных символов. Обычно непечатаемые символы выводятся в виде управляющих символов или в числовом формате. Этот параметр приводит к тому, что при выводе символов будет использоваться полный набор символов дисплея IBM. d Целое число выводится в виде десятичного значения. f[#] Формат с плавающей точкой с заданным числом цифр. Если вы не задаете число цифр, то используется столько цифр, сколько необходимо. m Выражение со ссылкой на память выводится в виде шестнадцатиричных байт. md Выражение со ссылкой на память выводится в виде десятичных байт. P Выводится необработанное значение указателя, показывающее сегмент, как имя регистра (если это возможно). Показывается также объект, на который указатель ссылается. Если управление форматом не задано, то это используется по умолчанию. s Выводится массив или указатель на массив символов (строка, заключенная в кавычки). Строка завершается нулевым символом. x или h Целое выводится в виде шестнадцатиричного значения. ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД |