Глава 5. Ассемблеры MASM и TASM
В данной главе мы поговорим о двух конкурирующих продуктах MASM и TASM, их плюсах и минусах, общих чертах и различиях. Когда в конце 80-х я впервые "пересел" на "айбиэмки", первый вопрос, который я задал знающим людям, был об ассемблере. До этого я программировал на разных компьютерах, в основном имеющих весьма ограниченные ресурсы. Естественно, что основным языком на таких компьютерах был ассемблер 27. Мне дали MASM, кажется, это была вторая версия. Удивительно, но тогда на ассемблере я начал писать что-то типа баз данных. Проект мой не был закончен, но к ассемблеру я прикипел основательно. Потом мне попался Турбо Ассемблер версии 1.0. Он работал гораздо быстрее MASM. В дальнейшем мне приходилось использовать то один, то другой ассемблер. Как Вы, наверное, уже поняли, первая любовь оказалась сильнее, но теперь нам придется серьезно поговорить о том, что же все-таки предпочтительнее использовать при программировании в операционной системе Windows.
27 Одно время в образовании был широко распространен персональный компьютер "Ямаха", ОЗУ которого составляла всего 64 Кб (потом 128). Писать для такого компьютера, скажем, на языке Паскаль было, естественно, непозволительной роскошью.
Начнем со справочной информации о параметрах командной строки ML.EXE и TASM32.EXE. В начале рассмотрим транслятор ML.EXE.
Программа ML.EXE
Параметр | Комментарий |
---|---|
/? | Вывод помощи. |
/AT | Создать файл в формате .СОМ. Для программирования в Windows этот ключ, естественно, бесполезен. |
/Bl<linker> | Использовать альтернативный компоновщик. Предполагается автоматический запуск компоновщика. |
/c | Компиляция без компоновки. |
/Ср | Сохранение регистров пользовательских идентификаторов. Может использоваться для дополнительного контроля. |
/Cu | Приведение всех пользовательских идентификаторов к верхнему регистру. |
/Сх | Сохранение регистров пользовательских идентификаторов, объявленных PUBLIC и EXTERNAL. |
/coff | Создание объектных файлов в стандарте coff. Применение обязательно. |
Задание текстового макроса. Очень удобен для отладки с использованием условной компиляции. | |
/ЕР | Листинг: текст программы с включаемыми файлами. |
/F <hex> | Размер стека в байтах. Размер стека по умолчанию равен 1 Мб. |
/Fe<file> | Имя исполняемого файла. Имеет смысл без параметра /с. |
/Fl<file> | Создать файл листинга. |
/Fm<file> | Создать map-файл. Имеет смысл без опции /с. |
/Fo<file> | Задать имя объектного файла. |
/Fpi | Включение кода эмулятора сопроцессора. Начиная с 486-ого микропроцессора, данный параметр потерял актуальность. |
/Fr<file> | Включить ограниченную информацию браузера. |
/FR<file> | Включить полную информацию браузера. |
/G<c|d|z> | Использовать соглашение вызова Паскаль, Си, stdcall. |
/H<number> | Установить максимальную длину внешних имен. |
/I<name> | Добавить путь для inc-файлов. Допускается до 10 опций /I. |
/link <opt> | Опции командной строки компоновщика. Имеет смысл без опции /с. |
/nologo | Не показывать заголовочный текст компилятора. |
/Sa | Листинг максимального формата. |
/Sc | Включить в листинг синхронизацию. |
/Sf | Листинг первого прохода. |
/Sl<number> | Длина строки листинга. |
/Sn | Не включать в листинг таблицу символов. |
/Sp<number> | Высота страницы листинга. |
/Ss<string> | Текст подзаголовка листинга. |
/St<string> | Текст заголовка листинга. |
/Sx | Включить в листинг фрагменты условной компиляции. |
/Ta<file> | Для компилирования файлов, расширение которых не .asm. |
/W<number> | Устанавливает перечень событий компиляции, трактуемые как предупреждения. |
/WX | Трактовать предупреждения как ошибки. |
/w | Тоже что /W0 /WX. |
/X | Игнорировать путь, установленный переменной окружения INCLUDE. |
/Zd | Отладочная информация состоит только из номеров строк. |
/Zf | Объявить все имена PUBLIC. |
/Zi | Включить полную отладочную информацию. |
/Zm | Включить совместимость с MASM 5.01. |
/Zp<n> | Установить выравнивание структур. |
/Zs | Выполнять только проверку синтаксиса. |
Программа TASM32.EXE
Параметр | Комментарий |
---|---|
/? или /h | Вывод помощи. |
/a | Сегменты в объектном файле располагаются в алфавитном порядке. |
/s | Сегменты в объектном файле расположены в порядке их описания. |
Задание текстового макроса. Очень удобен для отладки с использованием условной компиляции. | |
/e | Включение кода эмуляции сопроцессора. |
/r | Разрешение инструкций сопроцессора. |
/i<string> | Добавить путь для inc-файлов. Синтаксис такой же, как у команды РАТН. |
/j<dir> | Определяет директиву, которая будет транслироваться перед трансляцией. |
/kh<number> | Задается максимальное количество идентификаторов. По умолчанию 16384. |
/l | Создавать файл листинга. |
/la | Показать в листинге код, вставляемый транслятором для организации интерфейса с языками высокого уровня. |
/ml | Различать прописные и строчные буквы в идентификаторах. |
/mx | Различать прописные и строчные буквы в идентификаторах PUBLIC и EXTERNAL. |
/mu | Считать все символы в идентификаторах как прописные. |
/mv<number> | Установить максимальную длину идентификатора. |
/m<number> | Установка количества проходов транслятора. По умолчанию это число равно 1. |
/n | Не выдавать в файле листинга таблицы идентификаторов. |
/os, /o, /op, /oi | Тип объектного кода: стандартный, оверлейный, Phar Lap, IBM. |
/p | Проверять наличие кода с побочными эффектами при работе в защищенном режиме. |
/q | Удаление из объектного кода лишней информации. |
/t | Подавление вывода всех сообщений при условном ассемблировании. |
/w0, /w1, /w2 | Уровень полноты сообщений: сообщения не генерируются, сообщения генерируются. |
/w-<xxx> /w+<xxx> | Генереция (+) или ее отсутствие (-) сообщений класса xxx. |
/x | Включить в листинг блоки условного ассемблирования. |
/z | Выводить не только сообщения об ошибках, но строку с ошибкой. |
/zi | Включить в объектный код информацию для отладки. |
/zd | Поместить в объектный код номера строк. |
/zn | Не помещать в объектный код отладочной информации. |
В этой таблице объяснение опции помещено под строкой, содержащей эту опцию.
/ALIGN:number
Определяет выравнивание секций в линейной модели. По умолчанию 4096.
/BASE:{address|@filename,key}
Определяет базовый адрес (адрес загрузки). По умолчанию для ЕХЕ-программы адрес 0х400000, для
DLL — 0х10000000.
/COMMENT:["]comment["]
Определяет комментарий, помещаемый в заголовок ЕХЕ- и DLL-файлов.
/DEBUG
Создает отладочную информацию для ЕХЕ- и DLL-файлов. Отладочная информация помещается в pdb-файл.
/DEBUGTYPE:{CV|COFF|BOTH}
CV — отладочная информация в формате Microsoft, COFF — отладочная информация в формате
COFF (Common Object File Format), BOTH — создаются оба вида отладочной информации.
/DEF:filename
Определяет DEF-файл.
/DEFAULTLIB:library
Добавляет одну библиотеку к списку используемых библиотек.
/DLL Создать DLL-файл.
/DRIVER[:{UPONLY|WDM}]
Используется для создания NT-драйвера (Kernel Mode Driver).
/ENTRY:symbol
Определяет стартовый адрес для ЕХЕ- и DLL-файлов.
/EXETYPE:DYNAMIC
Данная опция используется при создании VxD-драйвера.
/EXPORT:entryname[=internalname][,@ordinal[,NONAME]][,DATA]
Данная опция позволяет экспортировать функцию из вашей программы так, чтобы она была доступна
для других программ. При этом создается import-библиотека.
/FIXED[:NO]
Данная опция фиксирует базовый адрес, определенный в опции /BASE.
/FORCE[:{MULTIPLE|UNRESOLVED}]
Позволяет создавать исполняемый файл, даже если не найдено внешнее имя или имеется несколько
разных определений.
/GPSIZE:number
Определяет размер общих переменных для MIPS и Alpha платформ.
/HEAP:reserve[,commit]
Определяет размер кучи (HEAP) в байтах. По умолчанию этот размер равен одному мегабайту.
/IMPLIB:filename
Определяет имя import-библиотеки, если она создается.
/INCLUDE:symbol
Добавляет имя к таблице имен.
/INCREMENTAL:{YES|NO}
Если установлена опция /INCREMENTAL:YES, то в ЕХЕ добавляется дополнительная информация,
позволяющая быстрее перекомпилировать этот файл. По умолчанию это информация не добавляется.
/LARGEADDRESSAWARE[:NO]
Указывает, что приложение оперирует адресами, большими 2 Гб.
/LIBPATH:dir
Определяет библиотеку, которая в первую очередь разыскивается компоновщиком.
/MACHINE: {ALPHA|ARM|IX86|MIPS|MIPS16|MIPSR41XX|PPC|SH3|SH4}
Определяет платформу. В большинстве случаев это делать не приходится.
/MAP[:filename]
Дает команду создания МАР-файла.
/MAPINFO:{EXPORTS|FIXUPS|LINES}
Указывает компоновщику включить соответствующую информацию в МАР-файл.
/MERGE:from=to
Объединить секцию "from" с секцией "to" и присвоить имя "to".
/NODEFAULTLIB[:library]
Игнорирует все или конкретную библиотеку.
/NOENTRY
Необходимо для создания DLL-файла.
/NOLOGO
Не выводить начальное сообщение компоновщика.
/OPT:{ICF[,iterations]|NOICF|NOREF|NOWIN98|REF|WIN98}
Определяет способ оптимизации, которую выполняет компоновщик.
/ORDER:@filename
Оптимизация программы путем вставки определенных инициализированных данных (COMDAT).
/OUT:filename
Определяет выходной файл.
/PDB: {filename|NONE}
Определить имя файла, содержащего информацию для отладки.
/PDBTYPE:{CON[SOLIDATE]|SEPT[YPES]}
Определяет тип РDВ-файла.
/PROFILE
Используется для работы с профайлером (анализатором работы программы).
/RELEASE
Помещает контрольную сумму в выходной файл.
/SECTION:name,[E][R][W][S][D][K][L][P][X]
Данная опция позволяет изменить атрибут секции.
/STACK:reserve[,commit]
Определяет размер выделяемого стека. Commit — определяет размер памяти, интерпретируемый
операционной системой.
/STUB:filename
Определяет STUB-файл, запускающийся в системе MS DOS.
/SUBSYSTEM:{NATIVE|WINDOWS|CONSOLE|WINDOWSCE|POSIX}[,#[.##]]
Определяет, как запускать ЕХЕ-файл. CONSOLE — консольное приложение, WINDOWS — обычные
WINDOWS-приложения, NATIVE — приложение для Windows NT, POSIX — создает приложение в
POSIX-подсистеме WINDOWS NT.
/SWAPRUN:{CD|NET}
Сообщает операционной системе скопировать выходной файл в swap-файл (WINDOWS NT).
/VERBOSE[:LIB]
Заставляет выводить информацию о процессе компоновки.
/VERSION:#[.#]
Помещает информацию о версии в ЕХЕ-заголовок.
/VXD
Создать VXD-драйвер.
/WARN[:warninglevel]
Определяет количество возможных предупреждений, выдаваемых компоновщиком.
/WS:AGGRESSIVE
Несколько уменьшает скорость выполнения приложения (Windows NT). Операционная система удаляет
данное приложение из памяти в случае его простоя.
Программа TLINK32.EXE.
В пакетах Borland С, начиная с 1997 года, сосуществовали две программы для компоновки объектных файлов: tlink32.exe и ilink32.exe. Опции этих программ практически совпадали, ilink32.exe - инкрементальный, или пошаговый, компоновщик. Он хранит информацию о предыдущих компоновках, что позволяет значительно ускорить весь процесс повторных трансляций. В последнее время программа tlink32.exe вообще исчезла из поставки. В дальнейшем мы не будем делать различий между этими двумя программами. Опции, помеченные (+), появились в новых версиях ilink32.exe, а опции со знаком (-), наоборот, исчезли. В новых версиях для выделения опции используется "/" вместо тире.-m | Создать МАР-файл с информацией о сегментах и два листинга с PUBLIC-именами (в алфавитном и адресном порядке). |
-s | Детальная информация о сегментах в МАР-файле. |
-M | Поместить в МАР-файл сокращенные имена идентификаторов. |
-c | Различать прописные и заглавные буквы в PUBLIC и EXTERNAL именах. |
-Enn | Задает максимальное количество ошибок, приводящее к остановке компоновки. |
-P- | Запретить паковать сегменты. Имеет смысл для 16-битных приложений (-P — разрешить). |
-b:хххх | Задает базовый адрес. По умолчанию базовый адрес равен 400000Н. (+) |
-B:хххх | Аналогично опции -b, но не создает таблицу настройки. Ключи —b и -B могут несколько ускорить работу программы. |
-wxxx | Возможные предупреждения. Например, -w-stk игнорировать отсутствие стекового сегмента. |
-Txx | -Tpx PE image(x: е=ЕХЕ, d=DLL) Тип выходного файла. Tpe - создать ЕХЕ-файл. Tpd - создать DLL-файл. Tpp - создать пакетный файл. (+) |
-ax -ap -aa | -ар — создать консольное приложение, -аа — создать обычное Windows-приложение (GUI), -ad — создать 32-битный драйвер для Windows.(+) |
-r | Заставляет компоновщик выдавать информацию о процессе компоновки. |
-Vd.d | Помещает в ЕХЕ-заголовок ожидаемую версию Windows. |
-Ud.d | Поместить в заголовок ЕХЕ-файла номер версии программы. (+) |
-o | Импорт по номеру функции. (-) |
-Ao:nnnn | Определяет величину выравнивания (кратно 2, минимально 16). |
-Af:nnnn | Файл выравнивания. |
-Sc:xxxx | Определить размер стека. |
-S:xxxx | Определить размер резервного стека. Минимально 4К. |
-Hc:хххх | Определить размер специальной "кучи". |
-H:хххх | Определить размер резервной "кучи". |
-n | Нет библиотеки "по умолчанию". (-) |
-v | Поместить в исполняемый файл полную отладочную информацию. Можно использовать -v+ и -v- для селективного помещения отладочной информации в отдельные файлы. |
-j | Определить путь поиска OBJ-файлов. |
-L | Определить путь к LIB-библиотеке. |
-x | Не создавать МАР-файл. |
-Rr | Позволяет заменять или добавлять ресурсы. (+) |
-d | Установить задержку загрузки библиотеки DLL. Она будет загружаться лишь при вызове входной процедуры. (+) |
-Dxxxx | Поместить в PE-заголовок специальный дескриптор. |
-GC | Поместить в заголовок РЕ строку (или строки). Например -GC"Hellow!". (+) |
-GD | Генерировать Delphi-совместимый файл ресурсов. (+) |
-GF | Установить флаг для загрузочного модуля: SWAPNET - указание для операционной системы поместить загрузочный модуль в swap-файл и загружать его оттуда, если он расположен на сетевом устройстве. SWAPCD - аналогично предыдущему флагу, но для съемных устройств. UNIPROCESSOR - приложение не должно запускаться в мультипроцессорной системе. LARGEADDRESSAWARE - приложение использует адреса больше 4 Gb. AGGRESSIVE - операционная система удаляет приложение из памяти в случае его простоя.(+) |
-Gk | Заставляет компоновщик оставлять в случае ошибки те файлы, которые обычно в этом случае уничтожались.(+) |
-Gl | Генерировать LIB-файл.(+) |
-Gpr | Создавать пакет "времени исполнения".(+) |
-Gpd | Создать пакет "времени создания".(+) |
-Gn | Запретить пошаговую компиляцию.(+) |
-GS:string=[ECIRWSDKP] Добавляет флаги к уже существующим флагам секций.(+) | |
-Gz | Помещает в РЕ-заголовок контрольную сумму загрузочного модуля. |
На первый взгляд трудно выявить предпочтение между MASM32 и TASM32. Но все же:
- MASM32 несколько более богат возможностями. Я имею в виду опции командной строки.
- TASM32 перестал поддерживаться как отдельный продукт. В связи с этим MASM обошел конкурента по количеству содержащихся в пакете примеров, документации, библиотек и т.д.
- TASM32 осуществляет более сложный алгоритм вызова API-функций, а это приводит к тому, что исполняемые модули в TASM32 получаются несколько большими, чем в MASM32.
Завершая главу, приведу несколько простых примеров.
Включение в исполняемый файл отладочной информации. Если в исполняемый файл была включена отладочная информация, то фирменный отладчик позволяет работать одновременно и с текстом программы, и с дизассемблированным кодом. Это особенно удобно для языков высокого уровня, а для программ на ассемблере это весьма мощный инструмент отладки. Пусть текст программы содержится в файле PROG.ASM. Для того чтобы включить отладочную информацию в исполняемый модуль, используем при трансляции следующие ключи:
MASM:
ML /c /coff /Zd /Zi prog.asm
LINK /subsystem:windows /debug prog.obj
При этом кроме файла PROG.EXE на диске появится файл PROG.PDB, содержащий отладочные данные. Теперь для отладки следует запустить фирменный 32-битный отладчик фирмы Microsoft - Code View.
TASM:
TASM32 /ml /zi prog.asm
TLINK32 -aa -v prog.obj
В результате в модуль PROG.EXE будет включена отладочная информация. Для отладки такого модуля следует использовать 32-битный Turbo Debugger - TD32.EXE. На Рис. 1.5.1 представлено окно отладчика с отлаживаемой программой. Можно видеть, что на экране имеется и текст программы, и ее дизассемблированный код. Более подробно об отладчиках мы будем говорить в последней части книги.
Получение консольных и GUI приложений. О консольных приложениях речь еще впереди, здесь же я буду краток. Консольные приложения - это приложения, работающие с текстовым экраном, при этом они являются полнокровными 32- битными программами. О структуре консольных программ речь пойдет ниже, сейчас же заметим, что для получения консольного приложения с помощью TLINK32.EXE вместо ключа -aa следует использовать -ар. Что касается компоновщика из пакета MASM32, то здесь следует использовать ключ /subsystem:console вместо /subsystem:windows.
Рис. 1.5.1. Окно TD32.EXE с отлаживаемой программой.
Автоматическая компоновка. Транслятор ML.EXE обладает удобным свойством автоматического запуска компоновщика. Обычно мы игнорируем это свойство, используя ключ /c. Если не применять это ключ, то транслятор ML будет пытаться запустить программу LINK.EXE. Чтобы правильно провести всю трансляцию, необходимо еще указать опции компоновщика. Вот как будет выглядеть вся строка:
ML /coff prog.asm /LINK /subsystem:windows
He правда ли, удобно?
Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий