Последние записи
- TChromium (CEF3), сохранение изображений
- Как в Delphi XE обнулить таймер?
- Изменить цвет шрифта TextBox на форме
- Ресайз PNG без потери прозрачности
- Вывод на печать графического файла
- Взаимодействие через командную строку
- Перенести программу из Delphi в Lazarus
- Определить текущую ОС
- Автоматическая смена языка (раскладки клавиатуры)
- Сравнение языков на массивах. Часть 2
Интенсив по Python: Работа с API и фреймворками 24-26 ИЮНЯ 2022. Знаете Python, но хотите расширить свои навыки?
Slurm подготовили для вас особенный продукт! Оставить заявку по ссылке - https://slurm.club/3MeqNEk
Online-курс Java с оплатой после трудоустройства. Каждый выпускник получает предложение о работе
И зарплату на 30% выше ожидаемой, подробнее на сайте академии, ссылка - ttps://clck.ru/fCrQw
26th
Май
Компилирование FAR + MASM
Posted by Chas under Пост-обзор
Mikl___:
Приходится писать и под DOS, и под Windows, используя TASM, MASM, WASM (Watcom Assembler), FASM, NASM ? наш исходный файл имеет стандартное расширение asm, а в качестве результата требуется com, exe, dll, lib… А если мы пишем exe-файл для Windows ? тогда по разному нужно собирать exe под console или gui… Можно ли предельно упростить сборку из ASM-файлов и при этом не писать каждый раз новый bat-файл?
Для начала напишем bat-файл, который по щелчку мыши или по нажатию на Enter создает gui-шный файл под Windows, причем, если в той же папке будет rc-файл с тем же именем, тогда к нашему obj-файлу будет добавлен res-файл.
Пишем asm.bat следующего содержания
set filename=
set masm_path=\masm32
if exist %filename%.rc (
%masm_path%\bin\rc /v %filename%.rc
%masm_path%\bin\cvtres /machine:ix86 %filename%.res
%masm_path%\bin\ml /c /Cp /Gz /I%masm_path%\include /coff /nologo %filename%.asm || exit
%masm_path%\bin\Link /SUBSYSTEM:WINDOWS /ALIGN:16 ^
/LIBPATH:%masm_path%\lib /NOLOGO %filename%.obj %filename%.res || exit
del %filename%.res
) else (
%masm_path%\bin\ml /c /Cp /Gz /I%masm_path%\include /coff /nologo %filename%.asm || exit
%masm_path%\bin\Link /SUBSYSTEM:WINDOWS /ALIGN:16 ^
/LIBPATH:%masm_path%\lib /NOLOGO %filename%.obj
)
Получвшийся bat-файл работает в полуавтоматическом режиме. В первой строке «set filename=» вписываем имя нашего asm-файла и запускаем asm.bat, а чтобы наши bat-файлы не плодились, как тараканы, нужно этот asm.bat перетаскивать из проекта в проект. Согласитесь это не совсем то что мы хотели ? точнее совсем не то!
Far Menager, так же как до этого Norton commander, можно «приучить» к определенным действиям с файлами, имеющими одинаковое рассширение. Far Menager поддерживает ассоциации файлов, которые позволяют задавать разнообразные действия на запуск, редактирование и просмотр файлов, заданных маской (в данном случае маска «*.asm»). Можно добавлять новые ассоциации с помощью команды «Ассоциация файлов» в «Меню команд». Можно задать несколько ассоциаций для одного типа файлов и выбрать желаемую ассоциацию из меню. В списке ассоциаций доступны следующие действия:
Ins ? добавить новую ассоциацию;
F4 ? изменить настройки текущей ассоциации;
Del ? удалить текущую ассоциацию.
При запуске из командной строки, мы пишем примерно следущее:
> asm.bat msgbox.asm
asm.bat должен проанализировать коммандную строку, взять первый аргумент после своего имени, выделить из него название файла без расширения «.asm» и подставить это имя в переменную filename. Первый аргумент после имени программы обозначают как %1. Осталось научиться, как из полного имени файла выделять название файла без расширения. В ассоциированных командах используются специальные метасимволы, среди которых «!» означающий длинное имя без расширения. Ну вот ? знаний у нас достаточно для решения этой проблемы!
Теперь нужно подправить наш asm.bat ? на первой строке пишем
set filename=%1
Запускаем FAR ? жмем на F9 -> «Команды» -> «Ассоциации файлов» -> F4 -> «Маска файла» -> Набираем «*.asm» -> «Команда, выполняемая по Enter» -> Набираем «asm.bat !» а сам asm.bat скопируем в Windows\system32\. Теперь стоит по любому asm-файлу щелкнуть мышью или навети курсор и нажать на Enter, как будет запущен процесс компиляции и линковки. И asm.bat единственный! Но мы-то хотели, чтобы он был еще и универсальным…
Разделим наш asm-bat на несколько частей, допустим, в первой части asm.bat строки, которые собирают COM-файлы, во второй части ? строки, которые собирают из asm-файла EXE-файлы для DOS, в третьей ? EXE-файлы для Windows (причем, когда нам нужен GUI подставляется параметр /SUBSYSTEM:WINDOWS а когда нужна консоль ? параметр /SUBSYSTEM:CONSOLE), в четвертой ? DLL-файлы, в пятой ? SYS-файлы и т.д., а часть строк asm-bat будет общей для удаления «мусора» в виде obj-файлов и т.п.
Пусть первая строка нашего asm-файла скажет нашему универсальному bat-файлу какой тип файла у нас должен получиться в результате компиляции и линковки, для какой операционной системы (Windows, DOS) этот файл будет предназначен и каким ассемблером его нужно компилировать и линковать.
Если первую строку в asm-файле закомменировать, то она будет игнорироваться компилятором, но будет восприниматься командным процессором, который, в свою очередь, игнорирует символ «точка с запятой».
Итак первая строка asm-файла ? мы пишем на masm-диалекте и хотим получить com-файл под dos:
; masm com dos #
.model tiny
.code
org 100h
start:
. . .
Внутри нашего asm.bat вставим процедуру, которая по трем первым словам, разделенным пробелами или табуляцией составит метку, на которую передаст управление внутри asm.bat и там уже из нашего asm-файла сделают необходимый нам файл-результат
:read_settings
for /f "eol=# tokens=2-5" %%A in (%filename%.asm) do (
set compiler=%%A
set kind_of_file=%%B
set os=%%C
if %%D == # exit /b)
exit /b
Небольшие пояснения: :read_settings ? это имя нашей процедуры
Процедура читает первую строку asm-файла и работает с первыми пятью лексемами, разделенными пробелами или табуляцией и сопоставлет их с переменными начиная с %%A. Первое поле ? знак «;» экранирует всю строку, второе поле ? %%A, третье ? %%B, четвертое ? %%C, если пятое поле равно «#» ? выходим из процедуры.
for Запуск некоторой команды для каждого файла из заданного множества.
for {%переменная|%%переменная} in (множество) do команда
{%переменная|%%переменная}
Используйте %переменная для выполнения команды for из командной строки. Используйте %%переменная для выполнения команды for в пакетном файле. Переменные учитывают регистр и могут быть представлены со значением альфа, например, %A, %B или %C.
(множество)
Задает один или несколько файлов, каталогов, диапазон значений или текстовых строк, подлежащих обработке заданной командой. Скобки являются обязательными.
команда
Задает команду, которая будет выполнена для каждого файла, каталога диапазона значений или текстовой строки, включенной в указанный параметр (множество).
/f
передает первый отделенный пробелом элемент из каждой строки каждого файла.
eol=#
Задает символ конца строки (end of line).
tokens=x,y,m-n
Задает элементы, передаваемые из каждой строки в тело цикла for при каждой итерации. В результате размещаются дополнительные имена переменных. Форма m-n задает диапазон, указывающий элементы с m-го по n-ый.
set переменная=
Указывает имя переменной, значение которой требуется задать или изменить
exit /b
Выход из текущего пакетного сценария
goto метка
В пакетной программе передает управление Windows XP в строку, определенную меткой. Когда метка найдена, выполнение продолжается со следующей за ней строки.
call :метка [аргументы]
:метка
Указывает метку, на которую должно быть передано управление программы пакетной обработки. При использовании команды call с этим параметром создается новый контекст пакетного файла, а управление передается инструкции, следующей за указанной меткой. Когда первый раз встречается конец пакетного файла (после перехода на метку), управление возвращается на инструкцию, следующую за инструкцией call. При втором достижении конца файла выполнение пакетной программы прекращается. Команда goto :eof позволяет возвращать управление из пакетной программы.
аргументы
Задает данные командной строки, которые передаются в новый экземпляр программы пакетной обработки, начинающейся с :метки, включая параметры командной строки, имена файлов, пакетные параметры (в диапазоне от %1 до %9) или переменные (например %filename%).
cls
set filename=%1
call :read_settings %filename%
goto %compiler%%os%%kind_of_file%
Стираем с экрана (cls), получаем имя asm файла без расширения (set filename=%1) и передаем его в процедуру, в зависимости от требуемого ассемблера, ос и типа файла идем на соответствующую ветку (goto …). Далее, по значениям в переменых compiler, kind_of_file, os обрабатываем asm-файл. Например, часть asm.bat собирающая на masm com-файл под dos выглядит вот так
. . .
:masmdoscom
if exist %filename%.%kind_of_file% del %filename%.%kind_of_file%
ml /AT %filename%.asm
del %filename%.obj
exit
. . .
Так как внутри нашего asm.bat появилась процедура, придется внести небольшое изменение в запуск ассоциированного файла.
Запускаем FAR ? жмем на F9 -> «Команды» -> «Ассоциации файлов» -> F4 -> «Маска файла» -> Набираем «*.asm» -> «Команда, выполняемая по Enter» -> Набираем «call asm.bat !»
ниже полное содержание asm.bat, который я использую на своем компьютере
cls
set filename=%1
call :read_settings %filename%
@echo %compiler% %os% %kind_of_file%
if exist %filename%.exe del %filename%.exe
if exist %filename%.com del %filename%.com
if exist %filename%.dll del %filename%.dll
set %compiler%_path=d:\Aquila
goto :%compiler%%os%%kind_of_file%
:wasmwindowsgui
%wasm_path%\bin\wasm -6prs -mf -i%wasm_path%\include\WASM %filename%.asm || exit
%wasm_path%\bin\wlink file %filename%.obj form windows nt op c LIBPath ^
%wasm_path%\lib\ Library user32.lib,kernel32.lib,gdi32.lib
goto :m1
:fasmdoscom
:fasmdosexe
%fasm_path%\bin\fasm %filename%.asm
exit
:goasmwindowsgui
%goasm_path%\bin\GoAsm %filename%
if exist %1.rc (
%goasm_path%\bin\GoRc /r %filename%.rc || exit
%goasm_path%\bin\GoLink %filename%.obj %filename%.res user32.dll kernel32.dll ^
gdi32.dll comctl32.dll shell32.dll ole32.dll comdlg32.dll || exit
del %filename%.res
) else (
%goasm_path%\bin\GoLink %filename%.obj user32.dll kernel32.dll gdi32.dll ^
comctl32.dll shell32.dll ole32.dll comdlg32.dll
)
goto :m1
:goasmwindowsconsole
%goasm_path%\bin\GoAsm %filename%
%goasm_path%\bin\GoLink /console %filename%.obj kernel32.dll user32.dll ^
winmm.dll gdi32.dll
goto :m1
:lzasmwindowsconsole
:lzasmwindowsgui
%lzasm_path%\bin\lzasm %filename%.asm
%lzasm_path%\bin\alink %filename%.obj -oPE -c -subsys %kind_of_file%
goto :m1
:lzasmdoscom
%lzasm_path%\bin\lzasm %filename%.asm
%lzasm_path%\bin\alink %filename%.obj -oCOM -c
goto :m1
:lzasmdosexe
%lzasm_path%\bin\lzasm %filename%.asm
%lzasm_path%\bin\alink %filename%.obj -oEXE -c
goto :m1
:masmwindowsgui
set masm_path=d:\masm32
if exist %filename%.rc (
%masm_path%\bin\rc /v %1.rc
%masm_path%\bin\cvtres /machine:ix86 %1.res
%masm_path%\bin\ml /c /Cp /Gz /I%masm_path%\include /coff /nologo %filename%.asm || exit
%masm_path%\bin\PoLink1 /SUBSYSTEM:WINDOWS /ALIGN:4 /MERGE:.data=.text ^
/LIBPATH:%masm_path%\lib /NOLOGO /STUB:%masm_path%\bin\stubby.exe %1.obj %filename%.res || exit
del %filename%.res
) else (
%masm_path%\bin\ml /c /Cp /Gz /I%masm_path%\include /coff /nologo %filename%.asm || exit
%masm_path%\bin\PoLink1 /SUBSYSTEM:WINDOWS /ALIGN:4 /MERGE:.data=.text ^
/LIBPATH:%masm_path%\lib /NOLOGO /STUB:%masm_path%\bin\stubby.exe %filename%.obj
)
goto :m1
:masmwindowsnative
if exist %1.sys del if exist %1.sys
set masm_path=d:\masm32
%masm_path%\bin\ml /c /Cp /Gz /I%masm_path%\include /nologo /c /coff %filename%.asm || exit
%masm_path%\bin\link /LIBPATH:%masm_path%\lib\ /nologo /driver /base:0x10000 ^
/align:32 /out:%filename%.sys /subsystem:native %filename%.obj || exit
goto :m1
:tasmwindowsgui
%tasm_path%\bin\tasm32 /I%tasm_path%\include\TASM /q /z %filename%.asm %filename%.obj /ml/m3
%tasm_path%\bin\ilink32 -L%tasm_path%\lib /Tpe /aa /c /o /x %filename%.obj
goto :m1
:tasmwindowsconsole
%tasm_path%\bin\tasm32 /I%tasm_path%\include\TASM %filename%.asm /ml /m3 /q /z %filename%.obj
%tasm_path%\bin\ilink32 -L%tasm_path%\lib /Tpe /ap /c /o /x %filename%.obj
goto :m1
:nasmwindowsconsole
:nasmwindowsgui
%nasm_path%\bin\nasmw -O1 -f bin %filename%.asm -o %filename%.exe ^
-I%nasm_path%\include\NASM\
exit
:nasmdoscom
:nasmdosexe
:nasmwindowsdll
%nasm_path%\bin\nasmw -f bin %filename%.asm -o %filename%.%kind_of_file% ^
-I%nasm_path%\include\NASM\
exit
:tasmdoscom
%tasm_path%\bin\tasm /m3 %filename%.asm
%tasm_path%\bin\tlink /t/x %filename%.obj
goto :m1
:tasmdosexe
%tasm_path%\bin\tasm /m3 %filename%.asm
%tasm_path%\bin\tlink /x %filename%.obj
goto :m1
:wasmdoscom
%wasm_path%\bin\wasm %filename%.asm
%wasm_path%\bin\wlink file %filename%.obj form dos com
goto :m1
:wasmdosexe
%wasm_path%\bin\wasm %filename%.asm
%wasm_path%\bin\wlink file %filename%.obj form dos
goto :m1
:poasmwindowsconsole
%poasm_path%\bin\poasm /Gz /I%poasm_path%\include\PoAsm %filename%.asm
%poasm_path%\bin\polink /SUBSYSTEM:CONSOLE /LIBPATH:%poasm_path%\lib /MERGE:.data=.text %filename%.obj
goto :m1
:masmdoscom
%masm_path%\bin\ml /AT /c %filename%.asm
%masm_path%\bin\link16 /T %filename%.obj,,,,,
goto :m1
:masmdosexe
%masm_path%\bin\ml /c %filename%.asm
%masm_path%\bin\link16 %filename%.obj,,,,,
:m1
if exist %filename%.map del %filename%.map
if exist %filename%.obj del %filename%.obj
if exist %filename%.ilc del %filename%.ilc
if exist %filename%.ild del %filename%.ild
if exist %filename%.ilf del %filename%.ilf
if exist %filename%.ils del %filename%.ils
if exist %filename%.tds del %filename%.tds
exit
:read_settings
for /f "eol=# tokens=2-5" %%A in (%filename%.asm) do (
set compiler=%%A
set os=%%B
set kind_of_file=%%C
if %%D == # exit /b )
exit /b
Если вы не используете Far Menager, а набираете ASM-файлы в NotePad или еще где-то, тогда в bat-файле переделаем все «%1» на «%~n1», щелкаем по «Мой компьютер» -> «Сервис» -> «Свойства папки» -> «Типы файлов» и связываем ASM-файлы с файлом asm.bat.
Похожие статьи
Купить рекламу на сайте за 1000 руб
пишите сюда - alarforum@yandex.ru
Да и по любым другим вопросам пишите на почту
пеллетные котлы
Пеллетный котел Emtas
Наши форумы по программированию:
- Форум Web программирование (веб)
- Delphi форумы
- Форумы C (Си)
- Форум .NET Frameworks (точка нет фреймворки)
- Форум Java (джава)
- Форум низкоуровневое программирование
- Форум VBA (вба)
- Форум OpenGL
- Форум DirectX
- Форум CAD проектирование
- Форум по операционным системам
- Форум Software (Софт)
- Форум Hardware (Компьютерное железо)