Глава 17. Генерация листинга
Файл листинга полезно использовать, когда вы хотите точно
видеть, что генерирует Турбо Ассемблер при ассемблировании каждой
инструкции или директивы. Основу этого файла составляет исходный
файл, в который включен большой объем сопровождающей информации о
результатах ассемблирования. Турбо Ассемблер выводит для каждой
инструкции полученный машинный код, а также смещение в текущем
сегменте (на каждой строке с машинным кодом). Кроме того, Турбо
Ассемблер выводит в таблицах информацию о метках и сегментах, ис-
пользуемых в программе, включая значение и тип каждой метки и ат-
рибуты каждого сегмента.
Примечание: См. в Главе 2 описание параметров команд-
ной строки /l и /la.
Турбо Ассемблер может также по запросу генерировать таблицу
перекрестных ссылок для всех меток, используемых в исходном фай-
ле, в которой показано, где определяется каждая метка, и где на
нее имеется ссылка.
Примечание: См. в Главе 2 описание параметра командной
строки /c.
Формат листинга
В верхней части каждой страницы листинга выводится заголо-
вок, содержащий версию Турбо Ассемблера, с помощью которой выпол-
нено ассемблирование файла, дату и время ассемблирования и номер
страницы в листинге.
Файл листинга содержит две части: аннотированный листинг ис-
ходного кода и таблицу идентификаторов. Сначала выводится исход-
ный ассемблируемый код с заголовком, содержащим имя файла, в ко-
тором находится исходный код. Вывод исходного кода Ассемблера
сопровождается информацией о машинном коде, который ассемблирует
Турбо Ассемблер. Все ошибки или предупреждения, обнаруженные в
процессе ассемблирования, включаются в листинг непосредственно за
содержащей ошибку строкой.
Строки кода в файле листинга имеет следующий формат:
<глубина> <номер_строки> <смещение> <машинный_код> <исходный_код>
где <глубина> показывает уровень вложенности включаемых файлов
или макрокоманд в файле листинга.
Поле <номер_строки> содержит номер строки в файле листинга
(не включая заголовки). Номера строк особенно полезны при исполь-
зовании перекрестных ссылок Турбо Ассемблера, в которых указыва-
ются номер строк. Учтите, что поле <номер_строки> не соответству-
ет номерам строк исходного модуля. Например, если в файл
включается другой файл или выполняется макрорасширение, то значе-
ние поля <номер_строки> продолжает увеличиваться, хотя текущая
строка в исходном файле остается той же. Чтобы преобразовать но-
мер строки обратно в строку исходного кода, вы должны найти стро-
ку в файле листинга, и найти такую же строку в исходном коде (по
ее внешнему виду, а не по номеру).
Поле <смещение> представляет смещение в текущем сегменте на-
чала машинного кода, сгенерированного из соответствующей исходной
строки Турбо Ассемблером.
Поле <машинный_код> показывает фактическую последователь-
ность шестнадцатиричных значений размером в байт или слово, кото-
рые ассемблированы из соответствующей исходной строки на Ассемб-
лере.
Поле <исходный_код> - это просто исходная строка Ассемблера,
с комментариями и всем, что в ней содержится. Некоторые исходные
строки (например те, которые содержат только комментарии) не ге-
нерируют никакого машинного кода. Эти строки не содержат полей
<смещение> и <машинный_код>, но имеют номер строки.
Общие директивы управления листингом
Имеется ряд директив, которые позволяют вам управлять видом
файла листинга. Общие директивы управления листингом включают в
себя следующие директивы:
- .LIST ; только режим MASM
- .XLEST ; только режим MASM
- %LIST
- %NOLIST
- %CTLS
- %NOCTLS
- %SYMS
- %NOSYMS
Директива %LIST выводит в файл листинга все строки исходного
кода. Эта директива назначается по умолчанию при создании файла
листинга. Чтобы запретить вывод в листинг всех строк исходного
кода, используйте директиву %NOLIST. Приведем пример:
%NOLIST ; запретить листинг
INCLUDE MORE .INC
%LIST ; разрешить листинг
Директивы .LIST и .XLIST работают также, как директивы %LIST
и %NOLIST. Приведем пример:
.LIST
jmp xyz ; эта строка всегда выводится
.XLIST
add dx,ByteVar ; не содержится в листинге
Для управления включением в листинг директив управления лис-
тингом вы можете использовать директивы %CTL и %NOCTL. Директива
%CTLS приводит к включению в листинг директив управления листин-
гом (таких как %LIST, %INCL и т.д.). Обычно они в листинг не вы-
водятся. Эта директива действует для всех последующих строк, поэ-
тому сама директива %CTLS в листинг не выводится. Директива
%NOCTLS изменяет действие директивы %CTLS на обратное. После за-
дания директивы %NOCTLS все последующие директивы управления лис-
тингом в листинг включаться не будут (этот режим используется
Турбо Ассемблером по умолчанию, когда начинается ассемблирование
исходного файла). Например:
%CTLS
%NOLIST ; эта директива не будет включена в
; исходный файл
%NOCTLS
%LIST ; это не будет включаться в листинг
Для задания включения или не включения в файл листинга таб-
лицы идентификаторов вы можете использовать директивы %SYMS и
%NOSYMS (по умолчанию таблица идентификаторов выводится). Таблица
будет выводиться в конце файла листинга.
Приведем синтаксис директивы %SYMS:
%SYMS
Директива %NOSYMS имеет следующий синтаксис:
%NOSYMS
Директивы листинга включаемых файлов
В том случае, когда вы хотите вывести в файл листинга вклю-
чаемые файлы, вы можете разрешить или запретить эту возможность с
помощью директив %INCL и %NOINCL. По умолчанию включаемые файлы
обычно включаются в файл листинга. Директива %NOINCL приостанав-
ливает вывод в файл листинга всех последующих включаемых файлов,
пока он снова не будет разрешен директивой %INCL. Это полезно ис-
пользовать при наличии больших включаемых файлов, которые содер-
жат, например, много определений EQU, которые никогда не изменя-
ются.
Приведем пример:
%INCL
INCLUSE DEFS.INC ; содержимое выводится в листинг
%NOINCL
INCLUSE DEF1.INC ; содержимое не выводится в листинг
Директивы вывода блоков условного ассемблирования
Когда в исходном коде у вас содержатся блоки условного
ассемблирования, может оказаться желательным включение в листинг
всей информации. Вывод блоков условного ассемблирования может по-
мочь в тех случаях, когда вы хотите точно видеть поведение исход-
ного кода. В Турбо Ассемблере предусмотрены следующие директивы
вывода блоков условного ассемблирования:
- .LFCOND ; только для режима MASM
- .SFCOND ; только для режима MASM
- ,TFCOND ; только для режима MASM
- %CONDS
- %NOCONDS
Обычно Турбо Ассемблер не включает в листинг блоки условного
ассемблирования.
Директива %CONDS выводит в файл листинга все операторы ус-
ловного блока. При этом в файл листинга выводятся также все блоки
с условием false. Директива .LFCOND работает аналогично директиве
.LFCOND. Директива %NOCONDS предотвращает вывода в файл листинга
блоков условного ассемблирования с условием false. Директива
.SFCONDS работает аналогично директиве %NOCOND. Если вы хотите
переключить режим вывода блоков условного ассемблирования, ис-
пользуйте директиву .TFCOND.
Первая директива .TFCOND, которую обнаруживает Турбо Ассемб-
лер, разрешает вывод в листинг всех блоков условного ассемблиро-
вания. Если вы используете параметр командной строки /X, блоки
условного ассемблирования будут сначала выводиться в листинг, а
первая директива .TFCOND запретит их вывод. При каждом обнаруже-
нии в исходном файле директивы .TFCOND состояние вывода блоков
условного ассемблирования изменяется на обратное.
Для указания любой из этих директив поместите директиву на
отдельной строке исходного кода. Она будут влиять на непосредс-
твенно следующие за данной директивой блоки условного ассемблиро-
вания.
Директивы вывода в файл листинга макрокоманд
Обычно макрорасширения включаются в файлы листинга. Наличие
такой информации в файле листинга может оказаться очень полезной,
когда вы хотите видеть, что делается в исходном коде. В Турбо Ас-
семблере предусмотрено несколько директив, которые позволяют
включать и выключать данное средство. Это следующие директивы:
- .LALL ; только для режима MASM
- .SALL ; только для режима MASM
- .XALL ; только для режима MASM
- %MACS
- %NOMACS
Директива %MACS разрешает листинг всех макрорасширений. Тоже
самое делает директива .LALL, но она работает только в режиме
MASM. Вы можете использовать эти директивы для включения макро-
расширений в файл листинга.
Директива %MACS имеет следующий синтаксис:
%MACS
Директиву .LALL вы можете задать следующим образом:
.LALL
Если вы хотите подавить вывод всех операторов макрорасшире-
ния, используйте директивы %NOMACS или .SALL. Заметим, что эти
директивы можно использовать для выключения вывода макрорасшире-
ния в файл листинга.
Директива %NOMACS имеет следующий синтаксис:
%NOMACS
Директива .SALL задается следующим образом:
.SALL
Доступная в режиме MASM директива .XALL позволяет вам выво-
дить в листинг только те макрорасширения, которые генерируют код
или данные. Она имеет следующий синтаксис:
.XALL
Директивы вывода листинга перекрестных ссылок
В таблице идентификаторов листинга ссылок обычно выводится
большой объем информации о метках, группах и сегментах, но там не
сообщается, где определены сегменты, группы и метки и где они ис-
пользуются. Информация, выводимая в таблице перекрестных ссылок,
позволяет вам легко находить метки и следить за ходом выполнения
программы при ее отладке.
Существует несколько способов разрешения включения информа-
ции о перекрестных ссылках в файл листинга. Для получения инфор-
мации о перекрестных ссылках для всего файла вы можете использо-
вать параметр командной строки /c (подробности можно найти в
Главе 2), либо включить в исходный код директивы, позволяющие вам
разрешать и запрещать вывод перекрестных ссылок для отдельных
частей исходного кода. Это следующие директивы:
- .CREF ; только для режима MASM
- .XCREF ; только для режима MASM
- %CREF
- %NOCREF
- %CREFALL
- %CREFREF
- %CREFUREF
Директивы %CREF и .CREF позволяют вам собрать информацию о
перекрестных ссылках для всех идентификаторах в исходном файле,
начиная с данной точки. Директивы %CREF и .CREF отменяют действие
директив %NOCREF или .XCREF, которые запрещают сбор информации о
перекрестных ссылках.
Директивы %CREF и .CREF имеют следующий синтаксис:
%CREF
или
.CREF
Директивы %NOCREF и .XCREF имеют синтаксис:
%NOCREF [идентификатор, .]
или
.XCREF [идентификатор, .]
Если вы используете директивы %NOCREF и .XCREF без указания
идентификатора, то вывод перекрестных ссылок запрещается пол-
ностью. Если вы указываете одно или более имен идентификаторов,
то вывод перекрестных ссылок запрещается только для данных иден-
тификаторов.
Директива %CREFALL выводит в листинг перекрестные ссылки для
всех идентификаторов. Директива %CREFALL изменяет действие преды-
дущей директивы %CREFREF (запрещающей вывод в таблицу перекрест-
ных ссылок тех идентификаторов, на которые ссылки отсутствуют) на
обратное. После указания директивы %CREFALL все встречающиеся да-
лее в исходном файле идентификаторы будут включаться в листинг
перекрестных ссылок. Турбо Ассемблер использует это режим по
умолчанию а начале ассемблирования исходного файла.
Директивы %CREFALL, %CREFREF и %CREFUREF имеют следующий
синтаксис:
%CREFALL
%CREFREF
%CREFUREF
Параметры изменения формата листинга
Директивы управления форматом листинга изменяют формат файла
листинга. Вы можете использовать эти директивы, чтобы приспосо-
бить вид листинга под свой вкус и потребности.
Директива PAGE задает высоту и ширину страницы файла листин-
га и начинает новую страницу. Директива PAGE работает только в
режиме MASM. Она имеет следующий синтаксис:
PAGE [число_строк] [,число_столбцов]
PAGE +
где "число_строк" задает число строк, выводимых на странице лис-
тинга. Поле "число_столбцов" может принимать значения от 59 до
255 и задает число столбцов на странице. Если вы опустите один из
этих параметров, то текущая установка данного параметра остается
без изменений. Чтобы изменить только число столбцов, укажите пе-
ред этим параметром запятую, в противном случае вы измените число
строк.
Если вы укажете после директивы PAGE символ плюса (+), то
начинается новая страница, номер раздела увеличивается, а номер
страницы снова начинается с 1. Если вы используете директиву PAGE
без аргументов, то листинг возобновляется с новой страницы без
изменения номера раздела.
Директива %PAGESIZE работает также, как директива PAGE, но
она не начинает новую страницу и работает как в режиме Ideal, так
и в режиме MASM. Директива %PAGESIZE имеет следующий синтаксис:
%PAGESIZE [число_строк] [,число_столбцов]
Директива %NEWPAGE работает как директива PAGE без аргумен-
тов. Строки исходного текста после директивы %NEWPAGE будут начи-
наться в файле листинга с новой страницы. Директива %PAGESIZE
имеет следующий синтаксис:
%NEWPAGE
Директива %BIN устанавливает длину поля объектного кода в
файле листинга. Директива %BIN имеет синтаксис:
%BIN размер
где "размер" является константой. Если вы не используете эту ди-
рективу, то поле кода операции занимает в файле листинга до 20
позиций, например:
%BIN 12 ; устанавливает 12 позиций в листинге
Директива %DEPTH устанавливает размер поля глубины в файле
листинга. Эта директива имеет следующий синтаксис:
%DEPTH размер
где "размер" задает, скольку столбцов нужно зарезервировать в по-
ле глубины файла листинга. Это поле указывает уровень вложенности
включаемых файлов (INCLUDE) и макрорасширений. Если в качестве
размера вы укажете 0, то это поле в файле листинга не выводится.
Обычно не требуется задавать "размер" > 2, поскольку при этом без
усечения будет выводиться глубина до 99. По умолчанию это поле
имеет значение 1.
Директива %LINENUM задает размер поля номеров строк в файле
листинга. Данная директива имеет следующий синтаксис:
%LINENUM размер
Директива %LINENUM позволяет вам задать, сколько позиций
должны занимать номера строк в файле листинга. В поле "размер"
должна указываться константа. Если вы хотите минимизировать шири-
ну листинга, то можете уменьшить размер поля номеров строк. Кроме
того, если ваш файл содержит более 9999 строк, то размер этого
поля может потребоваться увеличить, чтобы номера не усекались. По
умолчанию номер строки занимает 4 столбца.
Директива %TRUNC усекает слишком длинные поля листинга. Она
имеет следующий синтаксис:
%TRUNC
Поле объектного кода в файле листинга имеет достаточно мес-
та для вывода кода, генерируемого большинством инструкций или ди-
рективами выделения данных. Размер этого поля можно настроить с
помощью директивы %BIN. Если отдельная строка исходного кода ге-
нерирует больше кода, чем можно вывести на одной строке, то оста-
ток автоматически усекается и таким образом будет невидимым. Если
вы хотите видеть весь генерируемый код, то используйте директиву
%NOTRUNC (слишком длинная строка при этом будет переноситься на
следующую). В противном случае используйте директиву %TRUNC. Вы
можете использовать эти инструкции для переключения режима усече-
ния.
Директива %NOTRUNC имеет следующий синтаксис:
%NOTRUNC
Директива %PCNT задает размер поля "сегмент:смещение" в фай-
ле листинга. Она имеет следующий синтаксис:
%PCNT размер
где "размер" - это число столбцов, которые вы хотите зарезервиро-
вать для смещения в текущем ассемблируемом сегменте. Турбо Ас-
семблер устанавливает размер, равный 4, для обычных 16-битовых
сегментов и 8 для 32-битовых сегментов процессора 80386. Директи-
ва %PCNT позволяет переопределить эти используемые по умолчанию
значения.
Директива TITLE, которую вы можете использовать только в ре-
жиме MASM, задает заголовок файла листинга. Эта директива имеет
следующий синтаксис:
TITLE текст
Заголовок "текст" будет выводиться в верхней части каждой
страницы после имени исходного файла и перед заголовком, заданным
по директиве SUBTTL. Директиву TITLE можно использовать в прог-
рамме только один раз.
Директива %TITLE работает также, как директива TITLE, но вы
можете использовать ее как в режиме MASM, так и в режиме Ideal.
Эта директива имеет следующий синтаксис:
%TITLE "текст"
Директива SUBTTL работает только в режиме MASM и задает под-
заголовок файла листинга. Она имеет следующий синтаксис:
SUBTTL текст
Подзаголовок выводится в верхней части каждой страницы после
имени исходного файла и после заголовка, заданного директивой
TITLE.
Директиву SUBTTL можно указывать в программе столько раз,
сколько требуется. Каждая директива изменяет подзаголовок, кото-
рый будет выводиться на следующей странице листинга.
Директива %SUBTTL работает аналогично директиве SUBTTL, но
ее можно указывать как в режиме Ideal, так и в режиме MASM. Эта
директива имеет синтаксис:
%SUBTTL "текст"
Директива %TABSIZE задает позицию табуляции в файле листин-
га. Данная директива имеет следующий синтаксис:
%TABSIZE размер
где "размер" - это число столбцов между двумя позициями табуляции
в файле листинга. По умолчанию это 8 столбцов.
Для задания длины поля исходного текста в файле листинга
можно использовать директиву %TEXT, которая имеет синтаксис:
%TEXT размер
где "размер" - это число столбцов, используемых для вывода в фай-
ле листинга исходных строк. Если размер исходной строки превышает
длину этого поля, то оно будет либо усекаться, либо переноситься
на следующую строку, в зависимости от использования директивы
%TRUNC или %NOTRUNC.
Чтобы сохранить все параметры управления листингом в
16-уровневом стеке, можно использовать директиву %PUSHCTL. Она
сохраняет только те параметры управления листингом, которые можно
разрешить или запретить (%INCL, %NOINCL и т.д.). Размеры полей
листинга не сохраняются. Данная директива особенно полезна в мак-
рокомандах, когда вы можете вызывать специальные режимы листинга,
которые отменяются при завершении макрорасширения.
Директива %PUSHCTL имеет синтаксис:
%PUSHCTL
Директива %POPCTL восстанавливает из стека параметры управ-
ления листингом и имеет следующий синтаксис:
%POPCTL
Эта директива восстанавливает параметры управления листингом
в те значения, которые они имели перед последней директивой
%PUSHCTL. Значения размеров полей листинга (%DEPTH, %PCNT и т.д.)
не восстанавливаются.
Назад | Содержание | Вперед