Последовательность создания исполняемого ехе-модуля на МАСМ
а) Сначала создаётся исходный текст программы на ассемблере, предположим, это myprog.asm. Инструментом является текстовый редактор, например, Notepad++.
б) Дальше выполняется трансляция (компиляция).
Примечание о терминах. Перевод исходного текста программы в машинопонятный код вообще-то называется «трансляция» (английское to translate означает «перевести»). Но трансляцию возможно осуществлять в режиме «компиляции» и в режиме «интерпретации». Ассемблерный ML.EXE, Си-шный GCC.EXE и подобные им в итоге создают исполняемые ехе-файлы и поэтому они – трансляторы типа «компиляторы». А вот, к примеру, PHP.EXE (применяется в веб-программировании) исходный текст интерпретирует – читает оператор, сразу переводит в машинный код и тут же отдает на исполнение; и так пока не выполнит всю программу. Поэтому PHP.EXE и подобные ему – трансляторы типа «интерпретаторы». В нашем курсе термины «компиляция» и «трансляция» следует считать синонимами.
Компиляция выполняется как обработка исходника myprog.asm программой-компилятором ML.EXE. Компилятор выполняет свою работу в два шага – макрорасширение и перевод в машинный код.
1) Макрорасширение выполняет часть компилятора, называемая «макрогенератор». Она внешне (как файл) никак не представлена, просто это часть функциональных возможностей компилятора ML. Суть её работы состоит в том, что она заменяет встречающиеся в исходнике имена подставляемых файлов и макросов их полными текстами. Разумеется, это здорово увеличивает объем исходного текста (отсюда термин «макрорасширение»). Вся эта работа выполняется по умолчанию в оперативной памяти, но у ML.EXE есть режим выполнения с ключом /PE, в результате которого можно создать на диске расширенный макрогенератором исходный файл и, таким образом, наглядно увидеть сделанную им работу.
2) Перевод расширенного текста в машинный код выполняет транслятор, являющийся основной функциональной частью ML.EXE. Согласно синтаксису ассемблера, исходный текст программы разделён на секции кода (там описываются команды) и данных (там описываются статические числовые и строковые переменные программы). Перевод (трансляция) выполняется для каждой секции в отдельности. Ссылки по адресам из одной секции в другую на этом этапе просто заполняются нулями и имеют статус «неразрешённых» (недовычисленных) внешних ссылок. Из сказанного понятно, что на этом этапе оттранслированные секции пока логически никак не связаны друг с другом. Вместе с сопутствующими данными эти секции записываются в двоичный файл специального формата COFF (Common Object File Format), называемый «объектным». По традиции этим файлам присваивают расширение obj. Для конкретности предположим, что результатом компиляции исходного файла myprog.asm стал объектный файл myprog.obj.
в) Последний шаг – компоновка. Компоновка (иногда используют кальку с английского - «линковка») – это фактически «сборка» ехе-модуля из отдельных секций, которые извлекаются из объектных файлов и кода подключаемых объектных библиотек. Этих исходных контейнеров секций (объектников *.obj и библиотек *.lib) может быть, в принципе, сколько угодно.
В процессе компоновки все однородные секции объединяются - отдельные секции кода сливаются в одну соединённую секцию кода, аналогично отдельные секции данных соединяются в общую секцию данных. Общая секция кода и общая секция данных соединяются вместе в т.н. «загрузочный модуль».
После этого компоновщик LINK.EXE «разрешает» (вычисляет окончательно) неразрешенные (до этого окончательно недоопределенные) внешние ссылки. Поскольку в загрузочном модуле все точки ссылок (обращений) по адресам и ответные точки (чтения-записи или передачи управления) уже «легли на своё место», то компоновщик имеет возможность измерить байтовые дистанции между тем и другим. Именно они и вписываются компоновщиком в поля «неразрешённых (до этого момента) внешних ссылок». С этого момента секции становятся логически связанными друг с другом.
Наконец, компоновщик создает на диске выходной файл ехе-модуля. Сначала он формирует в начале этого файла т.н. «ехе-префикс» - структуру со всякого рода служебной информацией. Потом, если говорить упрощенно, после заголовка в ехе-файл переписывается из оперативной памяти загрузочный модуль.
После этого ехе-модуль можно вызвать на исполнение обычными средствами операционной системы
Режимы компоновки
Компоновщик LINK.EXE способен создавать ехе-модули, которые вызываются на исполнение как консольные программы (ключ /SUBSYSTEM: CONSOLE). Они исполняются с использованием окна программы cmd.exe, которое автоматически открывается при их запуске. Такие программы малы по размеру, исполняются быстро и потребляют очень мало ресурсов. Правда, имеют скромный символьный интерфейс.
Программы с графическим интерфейсом пользователя (GUI – Graphic User Interface) также можно создавать на макроассемблере. По сравнению с консольными программами они должны создаваться не только из исходного файла и подключаемых библиотек. Для такой программы дополнительно нужно создать т.н. «ресурсный файл» (*.rc), в котором на макроязыке описываются все графические компоненты интерфейса – кнопки, иконки, поля текстового ввода-вывода и т.п. Для создания подобных файлов обычно используются специальные приложения.
Ресурсные файлы нужно откомпилировать специальным компилятором ресурсов. Их в МАСМе целых два – rc.exe и porc.exe, оба лежат в \bin. Результатом компиляции является «ресурсный объектный файл», с расширением res.
На этапе компоновки LINK.EXE собирает ехе-модуль не только из obj- и lib-файлов, но подключает также и res-файлы(ы) (ключ /SUBSYSTEM: WINDOWS). Получившийся ехе-модуль запускается в GUI-программу.