Туториал по FASM (Windows x32 API/Win32API), «Hello world!» / Хабр

0 Favorite

[

Коротко о FASM, ассемблере, WinAPI

  • Что такое FASM? – Это компилятор ассемблера (flat assembler).

  • Что такое ассемблер? – это машинные инструкции, то есть команды что делать процессору.

  • Что такое Windows API/WinAPI? – Это функции Windows, без них нельзя работать с Windows.

    Что дают WinAPI функции? – Очень много чего:

  • Работа с файлами.

  • Работа с окнами, отрисовка картинок, OpenGL, DirectX, GDI, и все в таком духе.

  • Взаимодействие с другими процессами.

  • Работа с портами.

  • Работа с консолью Windows

  • И еще очень много интересных функций.

Зачем нужен ассемблер?

На нем можно сделать все что угодно, от ОС до 3D игр.

Вот плюсы ассемблера:

А вот минусы ассемблера:

Что нужно для программирования на ассемблере (FASM)?

Установка компонентов (если можно так назвать)

Архив FASM-а распаковуем в C:\FASM или любой другой, но потом не забудьте настроить FASMEditor.

Архив FASMEdit-a распаковуем куда-то, в моем случае C:\FASM Editor 2.0

Архив OlyDbg распаковуем тоже куда-то, в моем случае C:\Users****DocumentsFasmEditorProjects

Настройка FASM Editor-a

Для этого его нужно запустить.

Сразу вас приветствует FASM Editor соей заставкой.

Теперь вам нужно зайти в вкладку “Сервис” (на картинке выделил синим) -> “Настройки…”

Жмем на кнопку с названием “…” и выбираем путь к файлам или папкам.

Теперь мы полностью готовы. К началу.

Пишем “Hello world!” на FASM

В Fasm Editor нужно нажать на кнопку слева сверху или “файл” -> “новый”. Выбираем любое, но можно выбрать “Console”

По началу вас это может напугать, но не боимся и разбираемся.

format PE Console ; говорим компилятору FASM какой файл делать

entry start ; говорим windows-у где из этой каши стартовать программу.

include 'win32a.inc' ; подключаем библиотеку FASM-а
;можно и без нее но будет очень сложно.

section '.data' data readable writeable ; секция данных

	hello db 'hello world!',0 ; наша строка которую нужно вывести

section '.code' code readable writeable executable ; секция кода

start: ; метка старта
	invoke printf, hello ; вызываем функцию printf
  
  invoke getch ; вызываем её для того чтоб программа не схлопнулась
  ;то есть не закрылась сразу.
  
  invoke ExitProcess, 0 ; говорим windows-у что у нас программа закончилась
  ; то есть нужно программу закрыть (завершить)

section '.idata' data import readable ; секция импорта
        library kernel, 'kernel32.dll', ; тут немного сложней, объясню чуть позже
                msvcrt, 'msvcrt.dll'
  
  import kernel,
  				ExitProcess, 'ExitProcess'
          
  import msvcrt,
  				printf, 'printf',
          getch, '_getch'

На самом деле из всей этой каши текста, команд всего 3: на 16, 18, 21 строках. (и то это не команды, а макросы. Мы к командам даже не подобрались)

Все остальное это просто подготовка программы к запуску.

Программа при запуске должна выглядеть так:

Самое интересное то что программа весит 2КБ. (Можно сократить и до 1КБ, но для упрощения и так пойдет)

Разбор: что значат этот весь текст?

На 1 строчке: “format PE Console” – это строчка говорит FASM-у какой файл скомпилировать, точнее 1 слово, все остальные слова это аргументы (можно так сказать).

PE – EXE файл, программа.

Console – говорим что это у нас консольная программа, но вам некто не мешает сделать из консольной программы оконную и наоборот.

Но есть кроме это остальные:

  • format MZ – EXE-файл НО под MS-DOS

  • format PE – EXE-файл под Windows, аналогично format PE GUI 4.0

  • format PE64 – EXE-файл под Windows, 64 битное приложение.

  • format PE GUI 4.0 – EXE-файл под Windows, графическое приложение.

  • format PE Console – EXE-файл под Windows, консольная программа. (просто подключается заранее консоль)

  • format PE Native – драйвер

  • format PE DLL – DLL-файл Windows, поясню позднее.

  • format COFF – OBJ-файл Linux

  • format MS COFF – аналогично предыдущему

  • format ELF – OBJ-файл для gcc (Linux)

  • format ELF64 – OBJ-файл для gcc (Linux), 64-bit

Сразу за командой (для компилятора) format PE Console идет ; это значит комментарий. К сожалению он есть только однострочный.

3 строка: entry start

5 строка: include 'win32a.inc'

  • Подключает к проекту файл, в данном случае “win32a.inc” он находиться в папке INCLUDE (в папке с FASM). этот файл создает константы и создает макросы для облегчения программирования.

8 строка: section '.data' data readable writeable

  • Секция данных, то есть программа делиться на секции (части), к этим секциям мы можем дать разрешение, имя.

Флаг “data” (Флаг это битбайтаргумент хранившей в себе какую-то информацию) говорит то что эта секция данных.

Флаги “readable writeable” говорят то что эта секция может читаться кем-то и записываться кем-то.

Текст ‘.data’ – имя секции

10 строка: hello db 'hello world!',0

hello – это метка, она может быть любого имени (почти, есть некоторые зарезервированные имена), эта метка хранит в себе адрес строки, это не переменная, а просто адрес, но чтобы не запоминать адреса в ручную, помогает FASM он запоминает адрес и потом когда видит эту метку снова, то он заменяет слово на адрес.

db – говорит то что под каждый символ резервируем 1 байт. То есть 1 символ храниться в одном байте.

‘hello world!’ – наша строка в кодировке ASCII

Что значит “,0” в конце строки? – это символ с номером 0 (или просто ноль), у вас на клавиатуре нет клавиши которая имела символ с номером 0, по этому этот символ используют как показатель конца строки. То есть это значит конец строки. Просто ноль записываем в байт после строки.

12 строка: section '.code' code readable writeable executable

Флаг “code” – говорит то что это секция кода.

Флаг “executable” – говорит то что эта секция исполняема, то есть в этой секции может выполняться код.

Все остальное уже разобрали.

14 строка: start:

Это второй вид меток. Просто эта метка указывает на следующую команду. Обратите внимание на то что в 3 строке мы указали start как метку входа в программу, это она и есть. Может иметь эта метка любое имя, главное не забудьте ваше новое имя метки вписать в entry

15 строка: invoke printf, hello

Это штото на подобие команды, но это и близко не команда ассемблера, а просто макрос.

Макрос – Это макро команда для компилятора, то есть вместо имени макроса подставляется что-то другое.

Например, макро команда invoke делиться на такие команды: (взят в пример команда с 15 строки)

push hello
call [printf]

Не переживайте если нечего не поняли.

17 строка: invoke getch

20 строка: invoke ExitProcess, 0

  • ExitProcess – WinAPI функция, она завершает программу. Она принимает значение, с которым завершиться, то есть код ошибки, ноль это нет ошибок.

23 строка: section '.idata' data import readable

Флаг “import” – говорит то что это секция импорта библиотек.

24-25 строки:

library kernel, 'kernel32.dll',
  				msvcrt, 'msvcrt.dll'
  • Макро команда “library” загружает DLL библиотеки в виртуальную память (не в ОЗУ, вам ОЗУ не хватит чтоб хранить всю виртуальную память).

Что такое DLL объясню позже.

kernel – имя которое привязывается к библиотеке, оно может быть любым.

Следующий текст после запятой: 'kernel32.dll' – это имя DLL библиотеки который вы хотите подключить.

Дальше есть знак это значит что текст на следующей строке нужно подставить в эту строку.

То есть код:

library kernel, 'kernel32.dll',
  				msvcrt, 'msvcrt.dll'

Заменяется на:

library kernel, 'kernel32.dll', msvcrt, 'msvcrt.dll'

Это нужно потому что у ассемблера 1 строка это 1 команда.

27-28 строка:

import kernel,
  			ExitProcess, 'ExitProcess'

import – Макро команда, которая загружает функции из DLL.

kernel – Имя к которой привязана DLL, может быть любым.

ExitProcess – Как будет называться функция в программе, это имя будет только в вашей программе, и по этому имени вы будете вызывать функцию. (WinAPI функция)

'ExitProcess' – Это имя функции которое будет загружено из DLL, то есть это имя функции которое прописано в DLL.

Дальше думаю не стоит объяснять, вроде все понятно.

Что такое DLL библиотека?

Это файл с расширением DLL. В этом файле прописаны функции (какие не будь). Это обычная программа, но которая не запускается по двойному щелчку, а загружается к программе в виртуальную память, и потом вызываются функции находящиеся в этой DLL.

Подводим итог

На ассемблере писать можно не зная самого языка, а используя всего лишь макро команды компилятора. За всю статью я упомянул всего 2 команды ассемблера это push hello и call [printf] . Что это значит расскажу в следующей статье.



Перейти в источник

Похожие статьи

О классах Program и Startup — инициализация ASP.NET приложения. Часть II: IWebHostBuilder и Startup / Хабр

0 Favorite [ Введение Это – продолжение статьи, первая часть которой была опубликована ранее. В той части был рассмотрен процесс инициализации, общий для любого приложения…

Ответы