Fasm
| flat assembler | |||
|---|---|---|---|
| Скриншот FASM с кодом из поставляемых примеров | |||
| Тип | компилятор | ||
| Разработчик | Томаш Грыштар | ||
| Написана на | язык ассемблера | ||
| Операционные системы | Unix-подобная операционная система, Windows, MS-DOS, DOS, Linux, OpenBSD, MenuetOS и KolibriOS | ||
| Первый выпуск | 1999 | ||
| Последняя версия | 1.73.32[1] (4 декабря 2023) | ||
| Репозиторий | github.com/tgrysztar/fasm | ||
| |||
| Лицензия | 2-пунктная лицензия BSD[вд][2] | ||
| Сайт | flatassembler.net (англ.) | ||
Fasm (стилизовано fasm под минускул; сокр. от flat assembler) — свободно распространяемый многопроходной ассемблер, написанный Томашем Грыштаром (пол. Tomasz Grysztar). Ассемблер fasm самодостаточен[1], изначально компилировался TASM-ом и стал способен собираться из собственных исходных кодов начиная с 4 мая 1999 в версии 0.90. Также fasm обладает небольшими размерами и очень высокой скоростью компиляции[источник не указан 1399 дней], имеет богатый и ёмкий макро-синтаксис, позволяющий автоматизировать множество рутинных задач[3][4]. Поддерживаются как объектные форматы, так и форматы исполняемых файлов. Это позволяет в большинстве случаев обойтись без компоновщика. В остальных случаях нужно использовать сторонние компоновщики, поскольку таковой вместе с fasm не распространяется.
Помимо базового набора инструкций процессора и сопроцессора[каких?], fasm поддерживает наборы инструкций MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, SSE4a, AVX, AVX-2, AVX-512, 3DNow!, дополнительные расширения AES, CLMUL, FMA, FMA4, XOP, а также EM64T и AMD64 (включая AMD SVM и Intel SMX).
Все вариации fasm непосредственно могут создавать выходные файлы в следующих, предустановленных в ассемблер, форматах: объектные файлы (стандартно для большинства ассемблеров): Executable and Linkable Format (ELF) или Common Object File Format (COFF, классический или в спецификации Microsoft), исполняемые файлы (не требует дополнительных компоновщиков): MZ, ELF или Portable Executable (PE) (WDM драйвера включительно, с возможностью настройки MZ DOS stub). Для генерации файлов в формате, отличном от предустановленных, есть формат бинарный файл, дающий программисту полный контроль за каждым байтом выходного файла, однако всю структуру, содержание и взаимосвязи такого файла программисту придётся описывать непосредственно.
В качестве родной целевой архитектуры используются архитектуры IA32 и x86-64. Присутствует неофициальное дополнение FASMARM, в котором родные целевые архитектуры ARM и ARM64. Реализация целевых архитектур, отличных от родной, аналогична подобной реализации на любом другом ассемблере — для этих целей используются макрокоманды и директивы определения данных.
История
Проект был начат в 1999 году Томашом Грыштаром (пол. Tomasz Grysztar), который на тот момент был студентом. Его исходный код был полностью написан на языке ассемблера TASM. Начиная с версии 0.90 (4 мая 1999) ассемблер fasm стал самодостаточен (его исходный код был адаптирован под родной диалект и собирался самим ассемблером fasm). В марте 2000 года fasm был опубликован в сети Интернет.
Изначально fasm запускался только из 16-разрядного плоского реального режима. Затем была добавлена поддержка 32-разрядности и в дополнение к ней поддержка DPMI. Исходный код был переписан таким образом, чтобы его легко можно было портировать под любую x86 операционную систему, поддерживающую 32-битную адресацию. Он был портирован на Windows, затем на Linux.
Принципы
- fasm стремится использовать минимально возможный набор директив препроцессора, то есть в предустановленном наборе директив не допускается внедрение новых директив, функциональность которых может быть достигнута имеющимся набором директив. Исключение — исторически сложившиеся взаимозаменяемые директивы.
- fasm — многопроходный ассемблер с оптимистическим предсказанием, то есть на первом же проходе ассемблер делает предположение, что все инструкции принимают свою минимально возможную по размеру форму. Многопроходность также позволяет неограниченно использовать выражения до их объявления.
- fasm не включает в выходной файл объявления не используемых процедур (реализовано посредством макрокоманд).
Содержимое выходного файла зависит только от содержания исходного кода и не зависит от окружения операционной системы или от параметров переданных в командной строке. Для тех кому данный принцип был неудобен для win32 была разработана обёртка «FA»[5], позволяющая подключить к файлу другой файл не непосредственно в коде, а через командную строку.
Исходный код для fasm может собираться сразу в исполняемый файл, минуя стадии создания промежуточных объектных файлов и их компоновки.
Процесс компиляции
Компиляция программы в fasm состоит из трёх стадий: препроцессирование, синтаксический анализ и ассемблирование.
Препроцессирование
Первая стадия (препроцессинг) выполняется в 1 проход, вначале исходный текст токенизируется, затем в нём распознаются и обрабатываются все директивы процессора, раскрываются все макросы и все символические константы. Поскольку дополнительных проходов этой стадией не предусмотрено, любой элемент языка, обрабатываемый на этой стадии, должен быть вначале объявлен, и только затем он может быть использован.
Синтаксический анализ
Вторая стадия, на этой стадии происходит дополнительная классификация токенов (так как даже типы токенов и требования к ним на стадиях препроцессирования и ассемблирования немного разные), для некоторых токенов создаются дополнительные структуры свойств, которые впоследствии будут использоваться при ассемблировании.
Ассемблирование
На стадии ассемблирования определяются адреса меток, обрабатываются условные директивы, раскрываются циклы и генерируется собственно программа. Стоит заметить, что fasm — многопроходной ассемблер, что позволяет ему делать некоторые оптимизации (например, генерировать короткий переход на метку вместо длинного). Во время прохода компилятор не всегда может вычислить выражение в условных директивах. В этом случае он делает какой-нибудь выбор и пытается скомпилировать дальше. Благодаря тому, что адреса меток, вычисленные на N-м проходе, используются на N+1-м проходе, этот процесс обычно сходится.
Формат записи инструкций
Используется Intel-синтаксис записи инструкций.
Единственное существенное отличие от формата, принятого в других ассемблерах (MASM, TASM в режиме совместимости с MASM) — значение ячейки памяти всегда записывается как [label_name], а просто label_name означает адрес (то есть порядковый номер) ячейки. Это позволяет обходиться без ключевого слова offset. Также в fasm при переопределении размера операнда вместо byte ptr пишется просто byte, вместо word ptr — word и т. д. Не позволяется использовать несколько квадратных скобок в одном операнде — таким образом, вместо [bx][si] необходимо писать [bx+si]. Эти изменения синтаксиса привели к более унифицированному и лёгкому для чтения коду.
Пример программы
Пример Windows-программы «Hello, world!», которая выводит это сообщение с помощью функции MessageBox и завершается:
format pe gui 4.0
entry start
include 'win32a.inc'
start:
invoke MessageBox,NULL,message,message,MB_OK
invoke ExitProcess,0
message db 'Hello, World!',0
data import
library kernel32,'kernel32.dll',\
user32,'user32.dll'
include 'api/kernel32.inc'
include 'api/user32.inc'
end data
include 'win32ax.inc'
.code
main:
invoke MessageBox,NULL,'Hello, World!','fasm message box:',MB_OK
invoke ExitProcess,0
.end main
Усложнённый вариант, с уточнением секций в PE-файле:
format pe gui
entry start
include 'win32a.inc'
section '.data' data readable writeable
message db 'Hello, World!',0
section '.code' code readable executable
start:
invoke MessageBox,NULL,message,message,MB_OK
invoke ExitProcess,0
section '.idata' import data readable writeable
library kernel32,'kernel32.dll',\
user32,'user32.dll'
import kernel32,\
ExitProcess,'ExitProcess'
import user32,\
MessageBox,'MessageBoxA'
Пример Windows-программы Множество Мандельброта.
format PE GUI 4.0
entry start
include 'win32a.inc'
section '.code' code readable executable
start:
mov [snam],0
invoke CreateMutex,0,0,mutexname
invoke GetLastError
cmp eax,ERROR_ALREADY_EXISTS
jne willwork
invoke ExitProcess,0
willwork:
invoke EnumDisplaySettings,0,-1,dmDeviceName
mov eax,[dmPelsWidth]
shr eax,2
shl eax,2
mov [wi],eax
mov [wwi],eax
mov eax,[dmPelsHeight]
mov [he],eax
mov [whe],eax
invoke GetCommandLine
mov esi,eax
cld
zikl:
lodsb
cmp al,0
je worki
cmp al,'/'
jne zikl
lodsb
cmp al,'p'
jne nofinti
nofin:
lodsb
cmp al,0
jne nofin
mov ebx,1
mov ecx,10
calcul:
dec esi
dec esi
xor eax,eax
lodsb
cmp al,' '
je calend
sub al,30h
mul ebx
add [ifparent],eax
mov eax,ebx
mul ecx
mov ebx,eax
jmp calcul
calend:
invoke GetWindowRect,[ifparent],spleft
mov ebx,[spright]
mov edx,[spleft]
sub ebx,edx
mov [wi],ebx
mov [wwi],ebx
mov eax,[spbottom]
mov ecx,[sptop]
sub eax,ecx
mov [he],eax
mov [whe],eax
mul ebx
mov [proizv],eax
mov [wstyle],WS_CHILD+WS_VISIBLE
jmp worki
nofinti:
cmp al,'c'
jne worki
mov [cflag],1
mov [wwi],640
mov eax,[dmPelsWidth]
sub eax,[wwi]
shr eax,1
mov [le],eax
mov [whe],302
invoke GetSystemMetrics,SM_CYCAPTION
add [whe],eax
invoke GetSystemMetrics,SM_CYFIXEDFRAME
shl eax,1
add [whe],eax
mov eax,[dmPelsHeight]
sub eax,[whe]
shr eax,1
mov [to],eax
mov [wi],452
mov [he],300
mov [wstyle],WS_VISIBLE+WS_SYSMENU
worki:
cld
mov edi,palet
mov esi,qalet
finit
fild [sds] ;127
fild [dtp] ;255 127
fldpi ;pi 255 127
splpal:
fild [gbs] ;0 pi 255 127
fadd st0,st0 ;0*2 pi 255 127
fmul st0,st1 ;0*2*pi pi 255 127
fdiv st0,st2 ;0*2*pi/255 pi 255 127
fld st0 ;0*2*pi/255 0*2*pi/255 pi 255 127
fcos ;cos 0*2*pi/255 pi 255 127
fmul st0,st4 ;cos*127 0*2*pi/255 pi 255 127
fadd st0,st4 ;cos*127+127 0*2*pi/255 pi 255 127
fistp [valb] ;0*2*pi/255 pi 255 127
fsin ;sin pi 255 127
fmul st0,st3 ;sin*127 pi 255 127
fadd st0,st3 ;sin*127+127 pi 255 127
fistp [valg] ;pi 255 127
mov ax,[seed1]
mov bx,[seed2]
mov cx,ax
mul [cont]
shl cx,3
add ch,cl
add dx,cx
add dx,bx
shl bx,2
add dx,bx
add dh,bl
shl bx,5
add dh,bl
add ax,1
adc dx,0
mov [seed1],ax
mov [seed2],dx
mov cx,dx
mov bx,256
mul bx
mov ax,cx
mov cx,dx
mul bx
add ax,cx
adc dx,0
mov ax,dx
and eax,0FFh
shl eax,8
or eax,[valg]
shl eax,8
or eax,[valb]
stosd
ror eax,8
xchg al,ah
rol eax,8
mov [esi],eax
add esi,4
inc [gbs]
cmp edi,palet+1020
jb splpal
fstp st0
fstp st0
fstp st0
mov eax,00FFFFFFh
stosd
mov [esi],eax
invoke GetModuleHandle,0
mov [clsHInstance],eax
invoke LoadIcon,eax,9758
mov [clsHIcon],eax
invoke LoadCursor,0,IDC_CROSS
mov [clsHCursor],eax
invoke RegisterClass,clsStyle
invoke CreateWindowEx,0,splclassname,spltitlename,[wstyle],[le],[to],[wwi],[whe],[ifparent],0,[clsHInstance],0
mov [newhwnd],eax
cmp [cflag],1
jne noconfig
invoke CreateWindowEx,0,stname,sabout,WS_CHILD+WS_VISIBLE,460,0,172,302,[newhwnd],3961,[clsHInstance],0
mov [hmess],eax
invoke CreateWindowEx,0,stname,0,SS_BITMAP+SS_SUNKEN+WS_CHILD+WS_VISIBLE,0,0,454,302,[newhwnd],3962,[clsHInstance],0
mov [newhwnd],eax
invoke CreateFontIndirect,lfHeight
mov [HNewFont],eax
invoke SendMessage,[hmess],WM_SETFONT,[HNewFont],1
noconfig:
invoke GetDC,[newhwnd]
mov [MyDC],eax
invoke CreateDIBSection,[MyDC],bhead,0,tut,0,0
mov [HBitmap],eax
invoke CreateCompatibleDC,[MyDC]
mov [CoDC],eax
invoke SelectObject,[CoDC],[HBitmap]
mov [OBitmap],eax
invoke CreateEvent,0,0,0,event1name
mov [ehndl],eax
invoke CreateEvent,0,0,0,event2name
mov [chndl],eax
invoke CreateEvent,0,0,0,event3name
mov [dhndl],eax
invoke CreateThread,0,0,Thr1Proc,0,0,Thr1ID
mov [t1hndl],eax
invoke CreateThread,0,0,Thr2Proc,0,0,Thr2ID
mov [t2hndl],eax
invoke CreateThread,0,0,Thr3Proc,0,0,Thr3ID
mov [t3hndl],eax
invoke GetCurrentProcess
invoke SetPriorityClass,eax,REALTIME_PRIORITY_CLASS
invoke SetThreadPriority,[t1hndl],THREAD_PRIORITY_TIME_CRITICAL
call pusk
msg_loop:
invoke GetMessage,msHWND,0,0,0
or eax,eax
jz end_loop
invoke DispatchMessage,msHWND
jmp msg_loop
end_loop:
invoke SelectObject,[CoDC],[OBitmap]
invoke DeleteObject,[HBitmap]
invoke DeleteDC,[CoDC]
invoke ReleaseDC,[newhwnd],[MyDC]
invoke CloseHandle,[ehndl]
invoke CloseHandle,[chndl]
invoke CloseHandle,[dhndl]
invoke CloseHandle,[t1hndl]
invoke CloseHandle,[t2hndl]
invoke CloseHandle,[t3hndl]
invoke DeleteObject,[HNewFont]
invoke ExitProcess,0
proc WndProc, hwnd,wmsg,wparam,lparam
push ebx esi edi
cmp [wmsg],WM_DESTROY
je wmdestroy
cmp [wmsg],WM_LBUTTONDOWN
je ldown
cmp [wmsg],WM_RBUTTONDOWN
je rdown
cmp [wmsg],WM_KEYDOWN
je keypressed
invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
jmp finish
ldown:
call coords
fdivp st1,st0
fstp [size]
call pusk
jmp my
rdown:
call coords
fmulp st1,st0
fstp [size]
call pusk
jmp my
coords:
mov eax,[lparam]
mov [tempx],ax
shr eax,16
mov edx,[he]
sub dx,ax
mov [tempy],dx
finit
fld [step]
fild [tempx]
fmul st0,st1
fld [labsc]
faddp st1,st0
fstp [absc]
fild [tempy]
fmulp st1,st0
fld [bordi]
faddp st1,st0
fstp [ordi]
fld [size]
fld1
fadd st0,st0
retn
pusk:
cld
finit
fild [wi] ;wi
fld [size] ;size wi
fdivrp st1,st0 ;size/wi
fld st0 ;step step
fstp [step] ;step
fld1 ;1 step
fld1 ;1 1 step
fadd st0,st1 ;2 1 step
fild [wi] ;wi 2 1 step
fsub st0,st2 ;wi-1 2 1 step
fdiv st0,st1 ;(wi-1)/2 2 1 step
fmul st0,st3 ;(wi-1)/2*step 2 1 step
fld [absc] ;absc (wi-1)/2*step 2 1 step
fsub st0,st1 ;labsc (wi-1)/2*step 2 1 step
fstp [labsc] ;(wi-1)/2*step 2 1 step
fstp st0 ;2 1 step
fild [he] ;he 2 1 step
fsub st0,st2 ;he-1 2 1 step
fdiv st0,st1 ;(he-1)/2 2 1 step
fmul st0,st3 ;(he-1)/2*step 2 1 step
fld [ordi] ;ordi (he-1)/2*step 2 1 step
fsub st0,st1 ;bordi (he-1)/2*step 2 1 step
fstp [bordi] ;(he-1)/2*step 2 1 step
finit
invoke SetEvent,[chndl]
invoke SetEvent,[dhndl]
retn
keypressed:
cmp [wparam],VK_LEFT
jne noleft
mov [Direction],1
jmp my
noleft:
cmp [wparam],VK_RIGHT
jne noright
mov [Direction],2
jmp my
noright:
cmp [wparam],VK_F1
jne nof1
finit
fld [absc1]
fstp [absc]
fld [ordi1]
fstp [ordi]
fld [size1]
fstp [size]
call pusk
jmp my
nof1:
cmp [wparam],VK_F2
jne nof2
finit
fld [absc2]
fstp [absc]
fld [ordi2]
fstp [ordi]
fld [size2]
fstp [size]
call pusk
jmp my
nof2:
cmp [wparam],VK_F3
jne nof3
finit
fld [absc3]
fstp [absc]
fld [ordi3]
fstp [ordi]
fld [size3]
fstp [size]
call pusk
jmp my
nof3:
cmp [wparam],VK_F4
jne nof4
finit
fld [absc4]
fstp [absc]
fld [ordi4]
fstp [ordi]
fld [size4]
fstp [size]
call pusk
jmp my
nof4:
cmp [wparam],VK_F5
jne nof5
finit
fld [absc5]
fstp [absc]
fld [ordi5]
fstp [ordi]
fld [size5]
fstp [size]
call pusk
jmp my
nof5:
cmp [wparam],VK_F6
jne nof6
mov [whatpal],palet
jmp my
nof6:
cmp [wparam],VK_F7
jne nof7
mov [whatpal],qalet
jmp my
nof7:
cmp [wparam],VK_F12
jne nof12
mov [iter],1048560
invoke SetEvent,[chndl]
invoke SetEvent,[dhndl]
jmp my
nof12:
cmp [wparam],VK_INSERT
jne noins
invoke GetOpenFileName,ofn
cmp eax,0
je my
invoke CreateFile,snam,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0
mov [hfile],eax
invoke ReadFile,[hfile],absc,10,hows,0
invoke ReadFile,[hfile],ordi,10,hows,0
invoke ReadFile,[hfile],size,10,hows,0
invoke CloseHandle,[hfile]
call pusk
jmp my
noins:
cmp [wparam],VK_END
jne noend
invoke GetSaveFileName,ofn
cmp eax,0
je my
invoke CreateFile,snam,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0
mov [hfile],eax
invoke WriteFile,[hfile],absc,10,hows,0
invoke WriteFile,[hfile],ordi,10,hows,0
invoke WriteFile,[hfile],size,10,hows,0
invoke CloseHandle,[hfile]
jmp my
noend:
cmp [wparam],VK_ESCAPE
jne my
wmdestroy:
invoke PostQuitMessage,0
my:
xor eax,eax
finish:
pop edi esi ebx
ret
endp
proc Thr1Proc,Paramx
align 16
again:
cmp [Direction],1
je revers
cld
mov esi,[whatpal]
mov edi,esi
lodsd
mov ecx,254
repe movsd
stosd
jmp endchoice
revers:
std
mov esi,[whatpal]
add esi,1016
mov edi,esi
lodsd
mov ecx,254
repe movsd
stosd
cld
endchoice:
invoke SetDIBColorTable,[CoDC],0,256,[whatpal]
; invoke WaitForSingleObject,[ehndl],16
invoke DwmFlush
invoke BitBlt,[MyDC],0,0,[wi],[he],[CoDC],0,0,SRCCOPY
jmp again
endp
proc Thr2Proc, paramx
align 16
agaj:
invoke WaitForSingleObject,[chndl],-1
finit
mov [y1],0
mov edi,[tut]
mov ebx,255
fld [t] ;t
fld [step] ;step t
vertp:
mov [x1],0
fld [bordi] ;ordi step t
fild [y1] ;y ordi step t
fmul st0,st2 ;y*step ordi step t
faddp st1,st0 ;imc step t
horip:
fld [labsc] ;absc imc step t
fild [x1] ;x absc imc step t
fmul st0,st3 ;x*step absc imc step t
faddp st1,st0 ;rec imc step t
fld st1 ;im rec imc step t
fld st1 ;re im rec imc step t
mov ecx,[iter]
align 16
iterat:
fld st1 ;im re im rec imc step t
fmul st2,st0 ;im re im*im rec imc step t
fld st1 ;re im re im*im rec imc step t
fmul st2,st0 ;re im re*re im*im rec imc step t
fmulp st1,st0 ;im*re re*re im*im rec imc step t
fld st1 ;re*re im*re re*re im*im rec imc step t
fadd st0,st3 ;re*re+im*im im*re re*re im*im rec imc step t
fcomip st7 ;im*re re*re im*im rec imc step t
ja nook
fadd st0,st0 ;im*re+im*re re*re im*im rec imc step t
fadd st0,st4 ;imnew re*re im*im rec imc step t
fxch st2 ;im*im re*re imnew rec imc step t
fsubp st1,st0 ;re*re-im*im imnew rec imc step t
fadd st0,st2 ;renew imnew rec imc step t
loop iterat
mov dl,255
jmp nexxt
nook:
fstp st0
mov eax,ecx
xor edx,edx
div ebx
nexxt:
mov al,dl
stosb
fstp st0
fstp st0
fstp st0
inc [x1]
mov eax,[wi]
cmp [x1],eax
jb horip
fstp st0
add edi,[wi]
inc [y1]
inc [y1]
mov eax,[he]
cmp [y1],eax
jb vertp
mov [iter],40080
jmp agaj
endp
proc Thr3Proc, paramx
align 16
agaj2:
invoke WaitForSingleObject,[dhndl],-1
finit
mov [y2],1
mov edi,[tut]
add edi,[wi]
mov ebx,255
fld [t] ;t
fld [step] ;step t
vertp2:
mov [x2],0
fld [bordi] ;ordi step t
fild [y2] ;y ordi step t
fmul st0,st2 ;y*step ordi step t
faddp st1,st0 ;imc step t
horip2:
fld [labsc] ;absc imc step t
fild [x2] ;x absc imc step t
fmul st0,st3 ;x*step absc imc step t
faddp st1,st0 ;rec imc step t
fld st1 ;im rec imc step t
fld st1 ;re im rec imc step t
mov ecx,[iter]
align 16
iterat2:
fld st1 ;im re im rec imc step t
fmul st2,st0 ;im re im*im rec imc step t
fld st1 ;re im re im*im rec imc step t
fmul st2,st0 ;re im re*re im*im rec imc step t
fmulp st1,st0 ;im*re re*re im*im rec imc step t
fld st1 ;re*re im*re re*re im*im rec imc step t
fadd st0,st3 ;re*re+im*im im*re re*re im*im rec imc step t
fcomip st7 ;im*re re*re im*im rec imc step t
ja nook2
fadd st0,st0 ;im*re+im*re re*re im*im rec imc step t
fadd st0,st4 ;imnew re*re im*im rec imc step t
fxch st2 ;im*im re*re imnew rec imc step t
fsubp st1,st0 ;re*re-im*im imnew rec imc step t
fadd st0,st2 ;renew imnew rec imc step t
loop iterat2
mov dl,255
jmp nexxt2
nook2:
fstp st0
mov eax,ecx
xor edx,edx
div ebx
nexxt2:
mov al,dl
stosb
fstp st0
fstp st0
fstp st0
inc [x2]
mov eax,[wi]
cmp [x2],eax
jb horip2
fstp st0
add edi,[wi]
inc [y2]
inc [y2]
mov eax,[he]
cmp [y2],eax
jb vertp2
mov [iter],40080
jmp agaj2
endp
section '.idata' import data readable writeable
library kernel,'KERNEL32.DLL',\
user,'USER32.DLL',\
gdi,'GDI32.DLL',\
ddllgg,'COMDLG32.DLL',\
dwmapi,'DWMAPI.DLL'
import kernel,\
GetModuleHandle,'GetModuleHandleA',\
GetCommandLine,'GetCommandLineA',\
CreateMutex,'CreateMutexA',\
CreateThread,'CreateThread',\
CreateEvent,'CreateEventA',\
SetEvent,'SetEvent',\
CreateFile,'CreateFileA',\
ReadFile,'ReadFile',\
WriteFile,'WriteFile',\
WaitForSingleObject,'WaitForSingleObject',\
CloseHandle,'CloseHandle',\
GetLastError,'GetLastError',\
GetCurrentProcess,'GetCurrentProcess',\
SetPriorityClass,'SetPriorityClass',\
SetThreadPriority,'SetThreadPriority',\
ExitProcess,'ExitProcess'
import user,\
RegisterClass,'RegisterClassA',\
CreateWindowEx,'CreateWindowExA',\
DefWindowProc,'DefWindowProcA',\
GetMessage,'GetMessageA',\
SendMessage,'SendMessageA',\
DispatchMessage,'DispatchMessageA',\
LoadCursor,'LoadCursorA',\
LoadIcon,'LoadIconA',\
GetDC,'GetDC',\
ReleaseDC,'ReleaseDC',\
GetWindowRect,'GetWindowRect',\
EnumDisplaySettings,'EnumDisplaySettingsA',\
GetSystemMetrics,'GetSystemMetrics',\
PostQuitMessage,'PostQuitMessage'
import gdi,\
CreateDIBSection,'CreateDIBSection',\
CreateCompatibleDC,'CreateCompatibleDC',\
SelectObject,'SelectObject',\
DeleteObject,'DeleteObject',\
DeleteDC,'DeleteDC',\
CreateFontIndirect,'CreateFontIndirectA',\
SetDIBColorTable,'SetDIBColorTable',\
BitBlt,'BitBlt'
import ddllgg,\
GetOpenFileName,'GetOpenFileNameA',\
GetSaveFileName,'GetSaveFileNameA'
import dwmapi,\
DwmFlush,'DwmFlush'
section '.data' data readable writeable
absc dt -0.77811577335160269
ordi dt 0.12063526609130849
size dt 0.00000000000008
t dt 10000000000000.0
iter dd 40080
absc1 dt -0.8274339775534058
ordi1 dt 0.1863544535074837
size1 dt 0.000000000000023
absc2 dt -0.839415805050327289052
ordi2 dt 0.223484686429087973440
size2 dt -0.00000000000014
absc3 dt -0.7849958448296
ordi3 dt -0.14659449428125
size3 dt 0.000000000035
absc4 dt -1.1896303680411870529
ordi4 dt 0.304275733768362228928
size4 dt 0.0000000000000028
absc5 dt -0.737724728811921468701
ordi5 dt 0.289595161073595381255
size5 dt 0.00000000000024
whatpal dd palet
clsStyle dd 0
clsLpfnWndProc dd WndProc
clsCbClsExtra dd 0
clsCbWndExtra dd 0
clsHInstance dd ?
clsHIcon dd ?
clsHCursor dd ?
clsHbrBackground dd COLOR_BTNFACE+1
clsLpszMenuName dd 0
clsLpszClassName dd splclassname
wstyle dd WS_POPUP+WS_VISIBLE
ifparent dd 0
mutexname db 'fdjfyyjdsjf',0
event1name db 'iidegfkdgpe',0
event2name db 'pyoupovppve',0
event3name db 'oyiotegfgwe',0
splclassname db 'ekjgddirkul',0
spltitlename db 'Spl Mandelbrot - Settings',0
stname db 'STATIC',0
sabout db 13,10,'Клавиши:',13,10
db 'F1-F5 - изображения',13,10
db 'F6,F7 - палитры',13,10
db 'Стрелки - направление',13,10
db 'Esc - выход',13,10
db 'Ins - загрузка',13,10
db 'End - сохранение',13,10,13,10
db 'Кнопки мыши:',13,10
db 'левая - увеличение',13,10
db 'правая - уменьшение',13,10,13,10
db 'Сайт автора:',13,10
db 'https://splushka.narod.ru/',0
lfHeight dd -14
lfWidth dd 0
lfEscapement dd 0
lfOrientation dd 0
lfWeight dd FW_NORMAL
lfItalic db 0
lfUnderline db 0
lfStrikeOut db 0
lfCharSet db RUSSIAN_CHARSET
lfOutPrecision db OUT_TT_PRECIS
lfClipPrecision db CLIP_DEFAULT_PRECIS
lfQuality db PROOF_QUALITY
lfPitchAndFamily db FIXED_PITCH+FF_MODERN
lfFaceName db 'Courier New',0
Direction dd 1
seed1 dw 0
seed2 dw 0
cont dw 8405h
gbs dd 0
sds dd 127
dtp dd 255
cflag dd 0
le dd 0
to dd 0
ofn dd 76
hWndOwner dd 0
hInstance dd 0
lpstrFilter dd sfilter
lpstrCustomFilter dd 0
nMaxCustFilter dd 0
nFilterIndex dd 0
lpstrFile dd snam
nMaxFile dd 1024
lpstrFileTitle dd 0
nMaxFileTitle dd 0
lpstrInitialDir dd 0
lpstrTitle dd 0
Flags dd OFN_LONGNAMES+OFN_HIDEREADONLY+OFN_OVERWRITEPROMPT+OFN_FILEMUSTEXIST+OFN_PATHMUSTEXIST
nFileOffset dw 0
nFileExtension dw 0
lpstrDefExt dd exte
lCustData dd 0
lpfnHook dd 0
lpTemplateName dd 0
sfilter db '*.plu params file \(^o^)/',0,'*.plu',0,0
exte db 'plu'
bhead dd 40
wi dd ?
he dd ?
dw 1
dw 8
dd 0
proizv dd ?
dd 2834
dd 2834
dd 0
dd 0
palet rd 256
qalet rd 256
HBitmap rd 1
OBitmap rd 1
MyDC rd 1
CoDC rd 1
Thr1ID rd 1
Thr2ID rd 1
Thr3ID rd 1
msHWND rd 1
msMESSAGE rd 1
msWPARAM rd 1
msLPARAM rd 1
msTIME rd 1
msPT rd 2
newhwnd rd 1
ehndl rd 1
chndl rd 1
dhndl rd 1
t1hndl rd 1
t2hndl rd 1
t3hndl rd 1
spleft rd 1
sptop rd 1
spright rd 1
spbottom rd 1
dmDeviceName rb 32
dmSpecVersion rw 1
dmDriverVersion rw 1
dmSize rw 1
dmDriverExtra rw 1
dmFields rd 1
dmOrientation rw 1
dmPaperSize rw 1
dmPaperLength rw 1
dmPaperWidth rw 1
dmScale rw 1
dmCopies rw 1
dmDefaultSource rw 1
dmPrintQuality rw 1
dmColor rw 1
dmDuplex rw 1
dmYResolution rw 1
dmTTOption rw 1
dmCollate rw 1
dmFormName rb 32
dmLogPixels rw 1
dmBitsPerPel rd 1
dmPelsWidth rd 1
dmPelsHeight rd 1
dmDisplayFlags rd 1
dmDisplayFrequency rd 1
wwi rd 1
whe rd 1
valg rd 1
valb rd 1
x1 rd 1
y1 rd 1
x2 rd 1
y2 rd 1
tut rd 1
step rt 1
labsc rt 1
bordi rt 1
HNewFont rd 1
hmess rd 1
snam rb 1024
hfile rd 1
hows rd 1
tempx rw 1
tempy rw 1
ERROR_ALREADY_EXISTS=183
Пример простой консольной программы в формате .COM:
org 100h
mov ah,9h
mov dx,hello
int 21h
mov ah,8h
int 21h
int 20h
hello db 13,10,"Hello, World!$"
Пример простой программы в формате ELF:
format ELF executable 3
entry start
segment readable executable
start:
mov eax,4
mov ebx,1
mov ecx,msg
mov edx,msg_size
int 0x80
mov eax,1
xor ebx,ebx
int 0x80
segment readable writeable
msg db 'Hello world!',0xA
msg_size = $-msg
Формат выходных файлов
С помощью директивы format можно указать следующие форматы выходных файлов:
MZ— исполняемые файлы DOS.PE— исполняемые файлы Windows (консольные, графические приложения и динамические библиотеки).PE64— исполняемые файлы 64-битных версий Windows.
COFF,MS COFF,MS64 COFF,ELF,ELF64— объектные файлы.ELF executable,ELF64 executable— исполняемые файлы в Unix-подобных системах.ARM— разработка энтузиастов[6].Binary— файлы произвольной структуры. Указав смещение 100h (org 100h), можно получить исполняемый файл формата .COM. Также с помощьюformat binaryможно компилировать файлы данных[7].
Операционные системы
- DOS;
- Windows: NT, XP, Vista, 7;
- Основанные на Linux — напрямую, через системные вызовы;
- FreeBSD;
- Другие, основанные на libc (Unix-подобные);
- MenuetOS, KolibriOS — не поставляется в стандартном пакете fasm, поставляется вместе с этими операционными системами.
Применение
Операционные системы, написанные на fasm:
- DexOS — автор Ville Turijanmaa
- MenuetOS — 32- и 64-битные графические операционные системы, автор Ville Turijanmaa
- KolibriOS — форк MenuetOS
Компиляторы, использующие fasm как бекэнд ассемблер:
IDE, основанное на fasm:
- Fresh — проект, поддерживаемый интернет сообществом, основанный John Found
Поддержка fasm в сторонних программных продуктах
Файл поддержки синтаксиса fasm поставляется вместе с базовым пакетом Vim.
Использование fasm поддерживают многие специализированные IDE, такие как RadASM, WinAsm Studio, Fresh (специально спроектированный под fasm) и т. д.
Примечания
- ↑ 1 2 Flat assembler download (англ.). flatassembler.net. Дата обращения: 26 августа 2019. Архивировано 31 августа 2019 года.
- ↑ https://github.com/tgrysztar/fasm/blob/752cc50465e38a98a2b6ed1161983988e4d5f61a/LICENSE.TXT
- ↑ Tomasz Grysztar. Flat Assembler Programmer’s Manual (англ.). Дата обращения: 27 мая 2012. Архивировано из оригинала 31 мая 2012 года.
- ↑ Randall Hyde. Which Assembler is the Best? (англ.). Дата обращения: 27 мая 2012. Архивировано из оригинала 31 мая 2012 года.
- ↑ FA
- ↑ FASMARM (англ.). flatassembler.net. Дата обращения: 27 сентября 2022. Архивировано 27 сентября 2022 года.
- ↑ Тема на официальном форуме о создании изображений с помощью макросов fasm (англ.). Дата обращения: 26 августа 2019. Архивировано 4 августа 2020 года.
Ссылки
- Официальный сайт (англ.). Дата обращения: 26 августа 2019.
- Официальный раздел по ARM (англ.). Дата обращения: 26 августа 2019.
- Макросы и директивы компилятора fasm. Дата обращения: 26 августа 2019.
- manual по fasm для новичков. Дата обращения: 26 августа 2019. Архивировано из оригинала 3 апреля 2019 года.
- JaeEditor 1.0 (FASM IDE) (англ.). Дата обращения: 26 августа 2019.








