E.D., это попытка(причём в правильном направлении), а не готовое, законченное решение, иначе оно было бы популярно, им бы пользовались.
rc.exe Утилита rc.exe запускается командной строкой: __RC__ [options]__file.rc___ Параметр rc-файл указывает имя файла определения ресурса, содержащего имена, типы, имена файлов и описания ресурсов, которые необходимо скомпилировать. Ключи данной программы: КлючиДействие/?, /hОтображает список параметров командной строки/cОпределяет кодовую страницу, используемую преобразованием NLS/dОпределяет символ препроцессора, который можно протестировать с помощью директивы #ifdef Можно задать условное ветвление в файле скрипта ресурсов о том, определяется ли термин в командной строке RC с помощью вариант -D. Предположим, что в вашем приложении есть всплывающее окно меню, меню отладки, которое нужно появляться только во время отладка. Когда вы компилируете приложение для обычного использования, Меню отладки не включено. Ваш файл скрипта ресурсов содержит следующие операторы для определения меню отладки: Код (C): MainMenu MENU BEGIN ... #ifdef DEBUG POPUP &Debug BEGIN MENUITEM &Memory usage, ID_MEMORY MENUITEM &Walk data heap, ID_WALK_HEAP END #endif END При компиляции ресурсов для отладочной версии приложение, вы включаете меню отладки следующим образом команда: Код (Text): rc -R -D DEBUG myapp.rc Работа с именами файлов и путями КлючиДействие/fmИмя exe-файлаRC создает один языконезависимый RES-файл и один языкозависимый (MUI) RES-файл с помощью script-file. Этот параметр должен использоваться вместе с параметром /foИмя rc-файла. RC вызывает языконезависимый RES-файл resname.res и языкозависимый (MUI) RES-файл mresname.res/foИмя rc-файлаRC создает объект RES-файл с именем resname с помощью script-file. Если параметр /fmИмя exe-файла также задан, RC создает один RES-файл, не зависящий от языка, и один RES-файл, зависящий от языка (MUI)./xПредотвращает проверку INCLUDE переменной среды компилятором ресурсов (RC) при поиске файлов заголовков или файлов ресурсов/iВыполняет поиск указанного каталога перед поиском каталогов, указанных переменной среды INCLUDE. С помощью этой опции rc.exe ищет каталоги в следующей последовательности: Текущий каталог Каталог или каталоги, которые указаны с помощью /i в том порядке, в котором они появляются на командной строке Список каталогов, указанных INCLUDE переменная среды, в порядке, в котором переменная Перечисляет их, если только не указать опцию /x Оптимизация КлючиДействие/kovertypeПерекрывающиеся типы ресурсов, которые RC помещает как в независимые от языка RES-файлы, так и в зависящие от языка (MUI) RES-файлы. Типы ресурсов, указанные параметром /k, должны быть подмножеством тех, которые указаны параметром /j. Например, J2, J3, K3 указывает, что RC помещает тип ресурса 3 как в файлы, не зависящие от языка, так и в зависящие от языка (MUI) файлы. Если параметр /q также задан, этот параметр игнорируется, а сведения в файле конфигурации RC имеют приоритет Эта опция позволяет выбрать, оптимизирует ли RC ваши ресурсы для Предзагрузка. Отключает функцию оптимизации загрузки в rc. Если этот вариант не подойдёт, компилятор организует сегменты и ресурсы в исполняемом файле, чтобы вся предварительно загруженная информация оставалась непрерывной. Этот функция позволяет Windows быстрее загружать приложение. Без опции /K все сегменты данных, неотбрасываемые сегменты кода и сегмент кода входной точки будут предварительно загружены, если только какой-либо сегмент и информация о его перемещении превышает 64 КБ. Если атрибут PRELOAD не назначен этим параметрам сегментов в файле module-definition (.def), когда вы связываете свое приложение, компилятор добавит атрибут предзагрузки и отобразят предупреждение. Ресурсы и сегменты будут иметь один и тот же сегмент выравнивание. Это выравнивание должно быть как можно меньше, чтобы предотвратить Последний исполняемый файл не станет слишком большим. Вы можете Задайте выравнивание с помощью опции /alignment в линкере КлючиДействие/g1Если задано значение /g1, rc создает файл MUI, если единственный локализуемый ресурс, включенный в файл MUI, является ресурсом версии. Если параметр /g1 не задан, rc не создаст файл MUI, если единственный локализуемый ресурс, включенный в файл MUI, является ресурсом версии/jloctypeЛокализуемые типы ресурсов, которые RC размещает в зависимом от языка (MUI) файле .RES. Если параметр /q также задан, этот параметр игнорируется, а сведения в файле конфигурации RC имеют приоритет/llangidЗадает язык по умолчанию для компиляции. Например, -l409 эквивалентен включению следующей инструкции в верхней части файла скрипта ресурса: LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US Дополнительные сведения см. в разделе "Идентификаторы языка"/nNull завершает все строки в строковой таблице/qMui.RCConfigФайл конфигурации RC, который соответствует формату файла конфигурации RC. Формат файла конфигурации RC позволяет компонентам самостоятельно описывать сведения о ресурсах, такие как управление версиями ресурсов, путь к файлу MUI, типы ресурсов и элементы. Этот файл указывает, какие ресурсы включаются в нейтральный по языку .RES файл, а какие ресурсы включаются в файл, зависящий от языка (MUI) .RES. Этот параметр и сведения, указанные в файле конфигурации RC, переопределяют параметры командной строки /j и /k./rИгнорируется. Ключ /r оставлен для поддержки совместимости с существующими makefile файлами/uНе определен символ препроцессора/vОтображает сообщения, которые сообщают о ходе выполнения компилятора Обычно rc не отображает сообщения, сообщающие о его прогрессе по мере компиляции. Однако можно заставить компилятор отображать эти данные сообщения с этой опциейСсылка: RC - Компилятор ресурсов - Digital Mars
Предлагаю для начала нашего небольшого эксперимента сделать такую систему: 1. Masm 64/32 (stable, safe) - которую не страшно будет запустить. 2. Базовые примеры. Перед добавлением примера - согласуем. 3. IDE. Интегрированные среды разработки (подключение). 4. Базовые утилиты (с описанием их команд/функций) в .html/.txt. Критерий добавления - охват. Закрываем информационные пустоты. Сделать -> посетить места. Будем решать возникающие при этом проблемы по мере их [поступления]. При этом нужно будет следить чтобы в sdk, obj, lib и т д не было скрытого исполняемого кода. --- Сообщение объединено, 5 мар 2026 --- Если дело сдвинется с мертвой точки. Будут собраны: 1. Masm 64/32 (stable, safe). 2. Базовые примеры. Предложу конструктивную помощь. До этого момента бессмысленно что-то обсуждать и заниматься мартышкиным трудом. --- Сообщение объединено, 5 мар 2026 --- --- Сообщение объединено, 5 мар 2026 --- Для обмена файлами сборки предлагаю использовать гугл-диск там нужно будет в одном месте поставить галочку чтобы расшарить доступ.
Кто решится поэксперементировать с MASM64/32 и Visual Studio совет(может кто не знает): скачать установщик с офицального сайта к нужной версии, а потом с помощью этого установщика, скачать себе какую-нибудь Visual Studio Professional 2022 или Enterprise 2022 (плюс от этого - можно выбрать нужное и не качать лишнего), а можно и на 2026 замахнуться, народ уже работает на ней. Где взять лекарство, я думаю, все знают, а кто не знает - подскажем, научим. И еще небольшое ИМХО - батники для компиляции делать максимально упрощёнными, типа: ml64 /c Proba_1_.asm link Proba_1_.obj kernel32.lib user32.lib /SUBSYSTEM:WINDOWS /entry:WinMain В VS - ещё пара строчек вверху добавится.
Еще одна весомая причина сделать сборку - не выкачивать каждый раз мегатонны говна из интернета. 1. Masm 64/32 (stable, safe) - которую не страшно будет запустить. 2. IDE. Интегрированные среды разработки (подключение). 3. Базовые примеры на ассемблере. Показывающие те или иные стороны/возможности.
Я тоже раньше так думал, но потом оказалось, что VS "под боком" всё равно нужна, так почему её не задействовать в компиляции MASM64/32. Да и потом, ну сделает Mikl___ сборку, а завтра плюнет и не будет делать, а VS она всегда будет, а обновить её, а заодно и MASM64/32 - вообще, не проблема. И потом, в VS ведь можно и линковать asm-файлы с C/C++ проектом, полученые от MASM64/32. И отлаживать ассемблерный код на ней можно и подсветку синтаксиса организовать с помощью плагина. Так что, вес студии себя окупает, как оказалось, к моему удивлению. Попробуйте - вдруг вам понравится.
IMHO я против того, чтобы bat-файл был максимально упрощен. Bat-файл (опять же IMHO) должен быть один на всю систему и привязан к расширению asm. Под Windows из asm могут быть скомпилированы следующие файлы SYS, DLL, EXE-GUI и EXE-CONSOLE. Причем если уж вам так охота, то нужно еще разделить на Win64 и Win32. Bat-файл должен получить имя asm-файла и, желательно, в первой строке asm-файла должно быть указано, какой тип файла вы желали бы получить. Как это сделано в FASMС целью управления форматом сгенерированного кода FASM использует директиву "format". Директива "format", за которой следует идентификатор, позволяет выбрать формат выходного файла. Директива помещается в начало asm-файла. Формат выходного файла "по-умолчанию" ― простой двоичный файл (flat binary file), его также можно выбрать с помощью директивы "format binary". За этой директивой может следовать ключевое слово "as" и строка в кавычках, указывающая расширение для выходного файла. Если имя выходного файла не было указано в командной строке, ассемблер будет использовать это расширение при создании выходного файла с именем asm-файла. Директивы "use16" и "use32" заставляют ассемблер генерировать 16-разрядный или 32-разрядный код, опуская настройку по умолчанию для выбранного выходного формата. "use64" позволяет генерировать код для long mode режима x64. Ниже описаны различные выходные форматы с указаниями, специфичными для этих форматов: Формат выходного файлаДирективаПримечаниепростой двоичный файлformat binaryMZ-COMuse16 org 100hMZ-EXEformat MZПо умолчанию код собирается в 16-разрядном форматеPortable Executable 32 разрядаWindows приложенияformat PE CONSOLEмогут следовать дополнительные настройки форматаformat PE GUIмогут следовать дополнительные настройки форматаformat PE GUI DLLмогут следовать дополнительные настройки форматаWindows kernel mode драйвераformat PE NATIVEмогут следовать дополнительные настройки форматаPortable Executable 64 разрядаformat PE64 CONSOLEмогут следовать дополнительные настройки форматаformat PE64 GUIмогут следовать дополнительные настройки форматаDinamic Link Libraryformat PE64 GUI DLLмогут следовать дополнительные настройки форматаformat PE64 NATIVEмогут следовать дополнительные настройки форматаExecutable and Linking Format (ELF) — формат исполняемых двоичных файлов, используемый в UNIX-подобных ОСformat ELFбудет сгенерирован 32-разрядный кодformat ELF64будет сгенерирован 64-разрядный кодCommon Object File Format (COFF) — формат исполняемых файлов, файлов объектного кода и динамических библиотекformat MS COFFбудет сгенерирован 32-разрядный кодformat MS64 COFFбудет сгенерирован 64-разрядный кодUnified Extensible Firmware Interface (UEFI) — «единый расширяемый интерфейс программного обеспечения» — интерфейс между ОС и микропрограммами, управляющими низкоуровневыми функциями оборудованияformat EFIformat EFIbootformat EFIruntimeWindows SubsystemValue (hex)DescriptionПримерIMAGE_SUBSYSTEM_NATIVE1Device drivers and native Windows processesformat PE nativeIMAGE_SUBSYSTEM_WINDOWS_GUI2The Windows graphical user interface subsystemformat PE GUIIMAGE_SUBSYSTEM_WINDOWS_CUI3The Windows character subsystemformat PE consoleIMAGE_SUBSYSTEM_EFI_APPLICATION0xAAn Extensible Firmware Interface applicationformat EFIIMAGE_SUBSYSTEM_EFI_BOOT_ SERVICE_DRIVER0xBAn EFI driver with boot servicesformat EFIbootIMAGE_SUBSYSTEM_EFI_RUNTIME_ DRIVER0xCAn EFI driver with run-time servicesformat EFIruntime format PE GUI 4.0 DLL at 7000000h on 'stub.exe' сперва ключевое слово для настройки целевой подсистемы далее могут следовать минимальная версия системы, под которую написано приложение и ее подверсия (версия и подверсией будут разделены точкой) ключевое слово "DLL" создает файл вывода как динамически подключаемую библиотеку (Dinamic Link Library) ключевое слово "WDM" создает файл вывода как Windows Driver Model (WDM-драйвер) ключевое слово "large" отмечает, что приложение может работать с адресами, размер которых свыше 2 гигабайт ключевое слово "NX" сигнализирует, что у исполняемого файла есть ограничению на исполнение кода, находящегося в неисполняемых разделах (сегменты данных, стека, ресурсах и т.п.), запрет исполнения, добавленный в таблицы страниц для предотвращения выполнения данных как кода. Используется для предотвращения уязвимости типа «переполнение буфера», позволяющей выполнять вредоносный код. Далее может следовать оператор "at" и числовое выражение, указывающее адрес базового образа PE файла Далее опционально может следовать оператор "on" со следующей за ним строкой в кавычках, содержащей имя файла, являющимся MZ-stub для PE программы (если указанный файл не в формате MZ, то он трактуется как простой двоичный исполняемый файл и конвертируется в формат MZ). По умолчанию код для этого формата 32-разрядный Для выбора формата Common Object File Format используйте: директиву "format COFF или "format MS COFF", зависит от того, хотите ли вы создать классический (DJGPP) или Microsoft-ский вариант файла COFF. Настройка кода по умолчанию для этого формата — 32-разрядная. Для создания файла в формате Microsoft COFF для архитектуры x64 используйте "format MS64 COFF" в таком случае по умолчанию будет сгенерирован код для long mode.
Коль уж речь зашла по FASM, хотел попутно поинтересоваться. А в MASM что-то подобное, наверное, не получится скомпилировать? MASM же бинарный формат не генерирует ? Или я что-то недопонимаю ? Код (ASM): ; PE Format Walkthrough ; http://sulaiman.thefreebizhost.com ; Created by : Sulaiman Chang ; References: ; 1. Create PE from scratch http://flatassembler.net/viewtopic.php?t=1309 ; 2. LUEVELSMEYER's description about PE file format ; 3. Microsoft PSDK July 2000 Edition ; 4. Iczelion's PE Tutorial IMAGE_DOS_HEADER: ;start : 00 (0) to 3F (63) .e_magic dw 0x5A4D ;00 01 .e_cblp dw 0x0080 ;02 03 .e_cp dw 0x0001 ;04 05 .e_crlc dw 0x0000 ;06 07 .e_cparhdr dw 0x0004 ;08 09 .e_minalloc dw 0x0010 ;10 11 .e_maxalloc dw 0xFFFF ;12 13 .e_ss dw 0x0000 ;14 15 .e_sp dw 0x0140 ;16 17 .e_csum dw 0x0000 ;18 19 .e_ip dw 0x0000 ;20 21 .e_cs dw 0x0000 ;22 23 .e_lfarlc dw 0x0040 ;24 25 .e_ovno dw 0x0000 ;26 27 .e_res rw 4 ;28 29 | 30 31 | 32 33 | 34 35 .e_oemid dw 0x0000 ;36 37 .e_oeminfo dw 0x0000 ;38 39 .e_res2 rw 10 ;40 41 | 42 43 | 44 45 | 46 47 | 48 49 | 50 51 .e_lfanew dd 0x00000080 ;52 53 | 54 55 | 56 57 | 58 59 ;60 61 62 63 ;===================================================================================================== DOS_STUB: ;start : 40 (64) to 7F (127) use16 ;DOS-STUB is a 16-bit program ;push cs <- we save 1 byte here ;pop ds <- we save another 1 byte here ;our DS is less 100h from CS, DS received PSP address mov dx,0x100 + 0x0B ;our db message starts at 0x0B because we save 3 bytes already mov ah,0x9 int 0x21 mov ah,0x4C ;save 1 byte here because we need to use AH only for function int 0x21 db 'This program cannot be run in DOS mode.',13,10,'$' rb 0x80 - $ ;0x80 - 0x75 = rb 0xB ;===================================================================================================== IMAGE_NT_HEADERS: ;start : 80 (128) to 1EF (495) .Signature db 'PE',0,0 ;128 131 IMAGE_FILE_HEADER: ;start : 84 (132) to 97 (151) .Machine dw 0x014C ;132 133 for intel 386 .NumberOfSection dw 0x0003 ;134 135 .TimeDateStamp dd %t ;136 139 .PointerToSymbolTable dd 0 ;140 143 .NumberOfSymbols dd 0 ;144 147 .SizeOfOptionalHeader dw 0x00E0 ;148 149 .Characteristic dw 0x818F ;150 151 IMAGE_OPTIONAL_HEADER: ;start : 98 (152) to F7 (247) * till IMAGE_DATA_DIRECTORY ;offset .Magic dw 0x010B ;152 153 .MajorLinkerVersion db 0x01 ;154 .MinorLinkerVersion db 0x37 ;155 .SizeOfCode dd 0 ;156 159 .SizeOfInitializedData dd 0 ;160 163 .SizeOfUninitializedData dd 0 ;164 167 .AddressOfEntryPoint dd 0x2000 ;168 171 = base + 2000 = 402000 (.code section) .BaseOfCode dd 0 ;172 175 .BaseOfData dd 0 ;176 179 .ImageBase dd 0x00400000 ;180 183 (default) .SectionAlignment dd 0x00001000 ;184 187 4096 bytes .FileAlignment dd 0x00000200 ;188 191 512 bytes (default) .MajorOperatingSystemVersion dw 1 ;192 193 .MinorOperatingSystemVersion dw 0 ;194 195 .MajorImageVersion dw 0 ;196 197 .MinorImageVersion dw 0 ;198 199 .MajorSubsystemVersion dw 4 ;200 201 .MinorSubsystemVersion dw 0 ;202 203 .Win32VersionValue dd 0 ;204 207 .SizeOfImage dd 0x00004000 ;208 211 .SizeOfHeaders dd 0x00000200 ;212 215 .CheckSum dd 0x0000EF20 ;216 219 .Subsystem dw 2 ;220 221 IMAGE_SUBSYSTEM_WINDOWS_GUI .DllCharacteristics dw 0 ;222 223 .SizeOfStackReserve dd 0x00001000 ;224 227 4096 bytes .SizeOfStackCommit dd 0x00001000 ;228 231 4096 bytes .SizeOfHeapReserve dd 0x00100000 ;232 235 1048576 bytes .SizeOfHeapCommit dd 0 ;236 239 .LoaderFlags dd 0 ;240 243 .NumberOfRvaAndSizes dd 0x10 ;244 247 16 decimal IMAGE_DATA_DIRECTORY: ;start : F8 (248) to 177 (375) * till IMAGE_SECTION_TABLE rq 1 ;248 255 .ImportTableVA dd 0x00003000 ;256 263 .ImportTableSize dd 0x00000090 rq 14 ;we don't need them also ;263 + 112 = 375 IMAGE_SECTION_TABLE: ;start : 178 (376) to 1EF (495) SECTION_1: .Name dq '.data' ;start : 178 (376) .VirtualSize dd 0x0000001D .VirtualAddress dd 0x00001000 ;-> in memory, it is 401000 .SizeOfRawData dd 0x00000200 .PointerToRawData dd 0x00000200 ;-> in our file, it is 0x200 (512) (offset from zero) .PointerToRelocations dd 0 .PointerToLineNumbers dd 0 .NumberOfRelocations dw 0 .NumberOfLineNumbers dw 0 .Characteristic dd 0xC0000040 ;end : 19F (415) SECTION_2: .Name dq '.code' ;start : 1A0 (416) .VirtualSize dd 0x0000001C .VirtualAddress dd 0x00002000 ;-> in memory, it is 402000 .SizeOfRawData dd 0x00000200 .PointerToRawData dd 0x00000400 ;-> in our file, it is 0x400 (1024) (offset from zero) .PointerToRelocations dd 0 .PointerToLineNumbers dd 0 .NumberOfRelocations dw 0 .NumberOfLineNumbers dw 0 .Characteristic dd 0x60000020 ;end : 1C7 (455) SECTION_3: .Name dq '.idata' ;start : 1C8 (456) .VirtualSize dd 0x00000090 .VirtualAddress dd 0x00003000 ;-> in memory, it is 403000 .SizeOfRawData dd 0x00000200 .PointerToRawData dd 0x00000600 ;-> in our file, it is 0x600 (1536) (offset from zero) .PointerToRelocations dd 0 .PointerToLineNumbers dd 0 .NumberOfRelocations dw 0 .NumberOfLineNumbers dw 0 .Characteristic dd 0x40000040 ;end : 1EF (495) ; | ;our SECTION_1 <PointerToRawData> points at 0x200 or (512) bytes from zero | ;since we are currently in file offset 1EF -------------------------------------------+ ;we need to "rb 0xF" or "rq 2" so that our address from 1F0 to 1FF are filled. rq 2 ;start : 1F0 (496) to 1FF (511) ;file offset = 0x200 ;memory offset = 0x401000 = (IMAGE_OPTIONAL_HEADER.ImageBase) + (SECTION_1.VirtualAddress) ;========================================================================================= SECTION_1_RAW_DATA: ;start : 200 (512) to 3FF (1023) org 0x401000 msgText db 'Message Text',0 ;\ ;512 524 ; } we use 1D (29) bytes here msgCaption db 'Message Caption',0 ;/ ;525 540 ; 541 to 1023 should be filled ; (1023 - 541) + 1 = 483 bytes ; we NEED to + 1 because 1023 is not INCLUDED when ; we use it to minus 541. rb 483 ;because our .code raw data start at 400 (1024) ;and because our IMAGE_OPTIONAL_HEADER > FileAlignment is 0x200 (512) bytes ;file offset = 0x400 ;memory offset = 0x402000 = (IMAGE_OPTIONAL_HEADER.ImageBase) + (SECTION_2.VirtualAddress) ;========================================================================================= org 0x2000 SECTION_2_RAW_DATA: ;start : 400 (1024) to 5FF (1535) use32 ;we are using 32-bit instruction push 0x40 ;6A 40 ;MB_OK + MB_ICONASTERIK + MB_APPLMODAL push msgCaption ;68 0D 10 40 00 ;push msgCaption push msgText ;68 00 00 40 00 ;push msgText push 0 ;6A 00 ;push HWND_DESKTOP call dword [0x0040307A] ;FF 15 7A 30 40 00 ;call MessageBoxA push 0 ;6A 00 ;push zero for ExitProcess parameter call dword [0x0040305C] ;FF 15 5C 30 40 00 ;call ExitProcess ;we have used 1C (28) bytes here ;1052 to 1535 should be filled ;(1535 - 1052) + 1 = 484 bytes rb 484 ;file offset = 0x600 ;memory offset = 0x403000 = (IMAGE_OPTIONAL_HEADER.ImageBase) + (SECTION_3.VirtualAddress) ;========================================================================================= org 0x3000 SECTION_3_RAW_DATA: ;start : 600 (1536) to 7FF (2047) IMAGE_IMPORT_DESCRIPTOR_1: .OriginalFirstThunk dd 0x00003054 ;3000 3003 .TimeDateStamp dd 0 ;3004 3007 .ForwarderChain dd 0 ;3008 300B .Name dd 0x0000303C ;300C 300F .FirstThunk dd 0x0000305C ;3010 3013 IMAGE_IMPORT_DESCRIPTOR_2: .OriginalFirstThunk dd 0x00003072 ;3014 3017 .TimeDateStamp dd 0 ;3018 301B .ForwarderChain dd 0 ;301C 301F .Name dd 0x00003049 ;3020 3023 .FirstThunk dd 0x0000307A ;3024 3027 ;terminated with IMAGE_IMPORT_DESCRIPTIOR that filled with 0 zeros rd 5 ;the structure size of IMAGE_IMPORT_DESCRIPTOR ;3028 to 303B ;Our DLL Name .KERNEL32 db 'KERNEL32.DLL',0 ;303C to 3048 .USER32 db 'USER32.DLL',0 ;3049 to 3053 IMAGE_THUNK_DATA32_1: .ForwarderString dd 0x00003064 ;3054 3057 .Function dd 0 ;3058 305B .Ordinal dd 0x00003064 ;305C 305F .AddressOfData dd 0 ;3060 3063 IMAGE_IMPORT_BY_NAME_1: .Hint dw 0 ;3064 3065 .Name db 'ExitProcess',0 ;3066 3071 IMAGE_THUNK_DATA32_2: .ForwarderString dd 0x00003082 ;3072 3075 .Function dd 0 ;3076 3079 .Ordinal dd 0x00003082 ;307A 307D .AddressOfData dd 0 ;307E 3081 IMAGE_IMPORT_BY_NAME_2: .Hint dw 0 ;3082 3083 .Name db 'MessageBoxA',0 ;3084 308F ;308F = 143 bytes used ;must filled 2047 - (1536 + 143) = 368 + 1 = 369 bytes rb 367 db 0
GRAFik, лучше о таких вещах спрашивать в отдельных топиках, но отвечу. MASM генерирует бинарный файл, это COM, но для этого нужен linker старой версии. Или можно использовать FASM, NASM, PoAsm. А конкретно в этом исходнике 32-разрядный PE с ExitProcess, MessageBoxA с заголовком и импортом. Exe в 369 байт. У меня есть такая же фигня в 96 байт
Т.е. если взять линкер старой версии и скомпилировать COM-файл, то можно получить такой же исполняемый PE-файл как у FASM в примере, который я запостил выше?
GRAFik, да... Research, добавлю. А сейчас давайте вернемся к главной теме. К bat-файлу. К тому, что написано выше, вопросы, предложения, опровержения, возражения есть?
С bat файлом легко определится когда есть примеры для компиляции и safe-stable сборка. Что целесообразно в .bat добавить а что не целесообразно относительно результата. Можно сделать следующим образом: я на windows 7 скачиваю vs. И кто-то еще независимо от меня скачивает vs. Потом с помощью форума оттуда из vs вытаскиваются нужные файлы и сравнивается их хэш. Если хэши у обоих людей совпали значит ничо не добавлялось. Делается это всего 1 раз. И вместе с файлами в txt и здесь на форуме сохраняются правильные хэши. Нужно 2 человека с windows 7. Откуда будем скачивать vs?
У меня лично никаких возражений нет. Просто я подумал, что новичкам для входа в тему, нужно и в ассемблер вникать, да ещё и с премудростями bat-файлов разбираться. Ну, я думаю, кому нужно разберуться. Так-то там ничего такого сверхсложного нет.
Как когда-то сказал Инди-Клерк у ассемблера достаточно высокий порог вхождения. Так что, если кому-то нужно → придется разбираться... Если вопросов, предложений, опровержений, возражений пока нет, то первое что понадобится, это создать ассоциации asm-файлов с файлом asm.bat Чтобы не повторяться, посмотрите как это делается в Сказках дядюшки Римуса о x64 → глава первая, → Братец Кролик создает ассоциации ассемблерных файлов с файлом asm.bat
Сделал небольшую программу для подсчета хеша файлов. Чтобы проверить сборки ms файлов. Работает без установки доп. библиотек, нужен только установленный python. Это самый неприятный этап, но он неизбежность и его нужно пройти. Чтобы каждый мог проверить что файлы компилятора и т.д. чистые. Код (Text): import hashlib from tkinter import Tk, messagebox from tkinter.filedialog import askopenfilename def print_s(s1, s2): messagebox.showinfo(s1, s2) def ShowMessage(s): print_s("MessageBox", s) def OpenFile(file_name, ext): Tk().withdraw() files = [('All Files', '*.*'), (f"All {ext}", f"*.{ext}")] return askopenfilename(initialfile="", initialdir=file_name, filetypes=files, defaultextension=f".{ext}") def compute_file_hash(filename, algorithm='sha256', blocksize=8192): hash_obj = hashlib.new(algorithm) with open(filename, 'rb') as f: while data := f.read(blocksize): hash_obj.update(data) return hash_obj.hexdigest() if __name__ == "__main__": filename = OpenFile('', '*') algo = 'sha256' file_hash = compute_file_hash(filename, algo) ShowMessage(f"Хеш ({algo}) файла '{filename}': {file_hash}") Могу сделать чтобы хэши и имена файлов сохранялись в текстовый файл. Чтобы проще было проверять. Жду ссылку откуда будем скачивать vs и список файлов который будем экспортировать. На этом непростом этапе будем проверять совместимость с другими версиями Win. После того как появится нормальная сборка можно обсуждать формат bat файла. От простого к сложному. Есть такая ссылка: https://learn.microsoft.com/en-us/cpp/assembler/masm/masm-for-x64-ml64-exe?view=msvc-170 На ней есть: https://learn.microsoft.com/en-us/visualstudio/install/install-visual-studio Предлагается скачать Visual Studio 2026. Есть сомнения что она пойдет на win 7. --- Сообщение объединено, 6 мар 2026 --- Финальная в версия с сохранением информации в файл. Этого будет достаточно: Код (Text): import hashlib, os from tkinter import Tk, messagebox from tkinter.filedialog import askopenfilename def print_s(s1, s2): messagebox.showinfo(s1, s2) def ShowMessage(s): print_s("MessageBox", s) def WriteStr(filename, Str): with open(filename, "a", encoding="utf-8") as f: f.write(Str) def ExtractFileName(file_name): return os.path.basename(file_name) def OpenFile(file_name, ext): Tk().withdraw() files = [('All Files', '*.*'), (f"All {ext}", f"*.{ext}")] return askopenfilename(initialfile="", initialdir=file_name, filetypes=files, defaultextension=f".{ext}") def compute_file_hash(filename, algorithm='sha256', blocksize=8192): hash_obj = hashlib.new(algorithm) with open(filename, 'rb') as f: while data := f.read(blocksize): hash_obj.update(data) return hash_obj.hexdigest() if __name__ == "__main__": algo = 'sha256' filename = OpenFile('', '*') file_hash = compute_file_hash(filename, algo) ShowMessage(f"Хеш ({algo}) файла '{filename}': {file_hash}") WriteStr("output.txt", f"{ExtractFileName(filename)}:{file_hash}\n") --- Сообщение объединено, 6 мар 2026 --- Когда будет раздражать вывод ShowMessage каждый раз, его можно закоментировать.
Я обычно проще делаю Код (Text): ml64 Proba_1_.asm /link kernel32.lib user32.lib /SUBSYSTEM:WINDOWS /entry:WinMain - два раза имя не придется писать И еще использую директивы includelib прямо в asm-файле, тогда (особенно если утилита консольная) вообще остается только точку входа указывать. Жаль, что как в masm32 нельзя ее указать прямо возле end.