FASM

 

Сравнение MASM и FASM на самом простом примере для начинающих Программистов.

 

Самая простая программа под WINDOWS

 

MASM

FASM

.386

.model flat, stdcall

 

include user32.inc

include kernel32.inc

include WINDOWS.INC

 

.data

MsgBoxCaption  db "Win32 Программа",0

MsgBoxText     db "Привет пользователь пк!",0

 

.code

start:

     invoke MessageBox, NULL, ADDR MsgBoxText,\

ADDR MsgBoxCaption, MB_OK

 

     invoke ExitProcess, NULL

end start

 

format PE GUI 4.0

 

 

include 'c:\fasmw\INCLUDE\WIN32AX.INC'

 

 

 

.data

MsgBoxCaption  db "Win32 Программа",0

MsgBoxText     db "Привет пользователь пк!",0

 

.code

start:

        invoke  MessageBox, NULL, MsgBoxText , MsgBoxCaption ,MB_OK

        invoke  ExitProcess, NULL

.end start   

 Как видно текст самой программы не сильно отличается. Это связано с тем что Fasm более новый ассемблер и перенял все хорошее у «старых» ассемблеров.

Разберем программу: .386 указывает что команды процессора используются не выше 386 неплохо для совместимости со старым железом но абсолютно не нужно в наши дни т.к. 486 старье, 586 Pentium PRO мало известная машина, ну и самый крутой проц это 686 реализованный в Pentium 2 или 3 точно не помню. Так что можно смело писать 686 только знать бы еще команды этих процессоров.

format PE GUI 4.0 более информационная строка описывает формат выходящего файла. Писать не обязательно если вы делаете стандартный windows exe файл, если надо dll, или не стандартный exe файл то надо указать дополнительные параметры например: format PE GUI 4.0 dll

 

include user32.inc, include kernel32.inc, include WINDOWS.INC-Подключаемые модули описывающие процедуры находящиеся в библиотеках user32.dll, kernel32.dll.

windows.inc всякие константы типа NULL заменяется на 0, MB_OKCANCEL заменяется на 1

include 'c:\fasmw\INCLUDE\WIN32AX.INC'. Аналогично только одна библиотека заменяет всё, также делает Windows приложения.

 

.data

MsgBoxCaption  db "Win32 Программа",0

MsgBoxText     db "Привет пользователь пк!",0

 

Секция дата: всякие данные которые в случае необходимости могут быть извлечены. MsgBoxCaption это метка (смещение) а другими словами просто число обозначающее начало слова «Win32 Программа».

Число ,0 обозначает конец строки.

MsgBoxText   аналогично MsgBoxCaption 

 

.code

start:

     invoke MessageBox, NULL, ADDR MsgBoxText, ADDR MsgBoxCaption, MB_OK

 

     invoke ExitProcess, NULL

end start

Секция код: набор команд процессора выстроенные определенным образом чтобы получилось, что нибудь полезное или вредное вам решать.

Start: это метка (смещение) обозначающее компилятору где начинать программу.

 

Invoke команда придуманная Стивеном Хатчессон (Сидней, Австралия) Для того чтобы упростить написание под windows

MessageBox, ExitProcess Подпрограммы находящиеся в разных DLL в Windows за ними идут аргументы (до хрена надо знать чтобы писать программы на ассемблере:-). У ExitProcess один аргумент NULL или просто 0, с MessageBox сложнее аж 4 аргумента.

 

NULL первый аргумент, для чего нужен не знаю в Интернете нечего про это нет, просто так надо.

ADDR MsgBoxText  пеpедача адpеса метки MsgBoxText . ADDR действителен только в контексте диpективы invoke. Вы не можете использовать его, чтобы пpисвоить адpес метки pегистpу или пеpеменной, напpимеp. В данном пpимеpе вы можете использовать offset вместо addr

B FASME addr писать не обязательно.

MB_OK тип окна с одной кнопкой ок меняете по своему усматрению.

 

end start наверное конец программы.

 

Сборка программы происходит в MASME из командной строки: сохраняете в текстовом формате с названием msgbox.asm

Затем из командной строки
ml /c /coff /Cp msgbox.asm  - Получится msgbox.obj не доделанный исполняемый файл, не понятно зачем он нужен.
link /SUBSYSTEM:WINDOWS  /LIBPATH:c:\masm32\lib  msgbox.obj  - и только теперь полноценная программа.
Немного заморочено, но что делать.
 
В FASME все проще запускаете FASMW.EXE вставляете текст, Нажимаете F9 и у вас готовая запущенная программа.
 

Теперь посмотрим эту программу под hiew

MASM

FASM

.00401000: 6A00                                push        000

.00401002: 6800304000                   push        000403000  ---↓ (1)

.00401007: 6810304000                   push        000403010  ---↓ (2)

.0040100C: 6A00                                push        000

.0040100E: E80D000000                   call        MessageBoxA ;user32

.00401013: 6A00                                 push        000

.00401015: E800000000                   call          ExitProcess ;kernel32

.00402000: 6A00                                  push        000

.00402002: 6800104000                     push        000401000  ---↑ (1)

.00402007: 6810104000                     push        000401010  ---↑ (2)

.0040200C: 6A00                                  push        000

.0040200E: FF157C304000                 call        MessageBoxA ;USER32

.00402014: 6A00                                   push        000

.00402016: FF155E304000                 call        ExitProcess ;KERNEL32

В MASME программа начинается с адреса 00401000 в FASME с 00402000 не много не стандартно, но это связано с тем что секция дата в начале и занимает место. Если её переместить в конец то адрес будет как и в MASME. MASM секцию дата всегда загоняет в конец.

Код несколько не такой как мы писали но это более правильный код. Команда invoke преобразует аргументы в последовательность команд в обратном порядке(так принято). MB_OK преобразуется в 0 и уходит в стек первым, тем не менее выполняется подпрограммой MessageBoxA последним (так устроен стек первым зашел последним вышел).

Вторым в стек уходит смещение на строку "Win32 Программа" вы можете это проверить нажав (1) в hiew он переведет курсор на это смещение.(подпрограмма

MessageBoxA это выполнит предпоследним)

Затем в стек уходит смещение на строку " Привет пользователь пк!" вы можете это проверить нажав (2) в hiew он переведет курсор на это смещение

Ну и последние это сама функция MessageBoxA она вызывается командой call.

Итак мы имеем 4 аргумента и одну функцию в обратном порядке. Тоже самое что и команда invoke.

Остальные строчки догадайтесь сами.

 

Теперь этот код не плохо было бы преобразовать в программу:

 

MASM

FASM

.386

.model flat, stdcall

 

include user32.inc

include kernel32.inc

.data

MsgBoxCaption  db "Win32 Программа",0

MsgBoxText     db "Привет пользователь пк!",0

 

.code

start:

            push        000

            push        offset MsgBoxCaption

            push        offset MsgBoxText

            push        000

            call        MessageBox ;user32

            push        000

            call        ExitProcess ;kernel32

 

end start    

 

 

 

include 'c:\fasmw\INCLUDE\WIN32AX.INC'

 

.data

MsgBoxCaption  db "Win32 Программа",0

MsgBoxText     db "Привет пользователь пк!",0

 

.code

start:

            push        000

            push        MsgBoxCaption ; смещение

            push        MsgBoxText        ; смещение

            push        000

            call        [MessageBoxA]     ;user32 используемая библиотека

            push        000

            call        [ExitProcess]           ;kernel32 используемая библиотека

 

.end start   

 

Код опять преобразовался в программу в MASME он возможно не будет работать потому что надо INC файлы изменить определенным образом.

В FASME все намного лучше код собирается без проблем, только функции надо взять в квадратные скобочки.

 

У Fasma в этом вопросе определенное преимущество так же можно писать под DOS, Linux MenuetOS одним и тем же компилятором.

Из недостатков: мало примеров в Интернете на русском языке.

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

 

 

Hosted by uCoz