Assembler для Windows

трах escort Directory Wide - sex-escort,tv



Глава 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. Применение обязательно.
/D<name>=[строка]Задание текстового макроса. Очень удобен для отладки с использованием условной компиляции.
/ЕРЛистинг: текст программы с включаемыми файлами.
/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Сегменты в объектном файле расположены в порядке их описания.
/d<name>=[string]Задание текстового макроса. Очень удобен для отладки с использованием условной компиляции.
/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Не помещать в объектный код отладочной информации.

Программа LINK.EXE(32 bit).

В этой таблице объяснение опции помещено под строкой, содержащей эту опцию.

/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Запретить пошаговую компиляцию.(+)
-GSstring-GS:string=[ECIRWSDKP] Добавляет флаги к уже существующим флагам секций.(+)
-GzПомещает в РЕ-заголовок контрольную сумму загрузочного модуля.

На первый взгляд трудно выявить предпочтение между MASM32 и TASM32. Но все же:

  1. MASM32 несколько более богат возможностями. Я имею в виду опции командной строки.
  2. TASM32 перестал поддерживаться как отдельный продукт. В связи с этим MASM обошел конкурента по количеству содержащихся в пакете примеров, документации, библиотек и т.д.
  3. 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 правда ли, удобно?