Лучшими примерами являются примеры с fasm, потому что fasm не использует компоновщик, который скрывает сложность программирования Windows другим непрозрачным слоем сложности.
Если вы довольны программой, которая пишет в окно графического интерфейса, то для этого есть пример в каталоге примеров fasm.
Если вам нужна консольная программа, которая позволяет перенаправление стандартного входа и стандартного выхода, что также возможно.
Существует примерная (helas крайне нетривиальная) программа, которая не использует графический интерфейс и работает строго с консолью, то есть с самим fasm. Это можно прореживать до самого необходимого. (Я написал четвертый компилятор, который является еще одним примером, отличным от графического интерфейса, но он также нетривиален).
Такая программа имеет следующую команду для генерации правильного исполняемого заголовка, обычно выполняемого компоновщиком.
FORMAT PE CONSOLE
Раздел с именем .idata содержит таблицу, которая помогает окнам при запуске связывать имена функций с адресами времени выполнения. Он также содержит ссылку на KERNEL.DLL, которая является операционной системой Windows.
section '.idata' import data readable writeable
dd 0,0,0,rva kernel_name,rva kernel_table
dd 0,0,0,0,0
kernel_table:
_ExitProcess@4 DD rva _ExitProcess
CreateFile DD rva _CreateFileA
...
...
_GetStdHandle@4 DD rva _GetStdHandle
DD 0
Формат таблицы определяется окнами и содержит имена, которые ищутся в системных файлах при запуске программы. FASM скрывает некоторые из
сложность позади ключевого слова rva. Таким образом, _ExitProcess @ 4 - это метка fasm, а _exitProcess - строка, которую ищет Windows.
Ваша программа находится в разделе «.text». Если вы объявляете этот раздел читабельным для записи и выполнения, это единственный раздел, который вам нужно добавить.
section '.text' code executable readable writable
Вы можете позвонить на все объекты, которые вы заявили в разделе .idata. Для консольной программы вам нужно _GetStdHandle, чтобы найти файловые дескрипторы для стандартных in и standardout (используя символические имена, такие как STD_INPUT_HANDLE, которые fasm находит во включаемом файле win32a.inc).
Когда у вас есть файловые дескрипторы, вы можете использовать WriteFile и ReadFile.
Все функции описаны в документации к kernel32. Вы, вероятно, знаете об этом, или не пытались бы программировать на ассемблере.
В итоге: есть таблица с именами asci, которые связаны с ОС Windows.
Во время запуска это преобразуется в таблицу вызываемых адресов, которую вы используете в своей программе.