Программирование на ассемблере графический интерфейс на Linux и Windows с использованием макросов NASMX
- Подробности
- Просмотров: 953
Всем привет. Хочу Вам рассказать как можно написать оконное приложения для Linux и Windows на ассемблере. Для этого нам понадобиться библиотека NASMX а также компилятор NASM.
NASM и Linux
Сначала начнем с Linux. В мы напишем оконное приложение для линукса с использованием библиотеки X11 (X Window System). Первым делом нужно скачать библиотеку макросов в nasmx (nasmx.sourceforge.net) и конечно же у вас должен быть установлен nasm, а также нам понадобиться gcc компилятор для сборки проекта.
Для всего этого создадим файл hello.asm в папке INC проекта NASMX со следующим содержимым:
BITS 32
;подключаем наши библиотеки
%include 'nasmx.inc'
%include 'x11/Xlib.inc'
ENTRY demo ;основная наша процедура
;делаем импорт библиотек которые будем использовать
IMPORT puts
IMPORT exit
IMPORT XStoreName
IMPORT XFreeGC
IMPORT XDrawImageString
IMPORT XDrawLine
IMPORT XSetForeground
IMPORT XSetBackground
%define RGB(r,g,b) (r << 16)+(g << 8)+(b)
; создаем константу которая будет указывать что должно обрабатывать окно
%assign OurInputMask ( KeyPressMask + KeyReleaseMask + ExposureMask )
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SECTION .data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
strCaption DB 'Hello World', 0 ;переменная которая будет в заголовке окна
strMessage DB "Hello World!" ;и эту переменную выведем в окне
lenMessage EQU ($-strMessage)
oError DD 0
strErrorDisplay DB 'XOpenDisplay: could not open connection to X server.', 0
strErrorCreation DB 'XCreateSimpleWindow: could not create window.', 0
strErrorShow DB 'XMapRaised: could not display window.', 0
hGC DD 0
hwin DD 0
hdisplay DD 0
event TIMES 20 DD 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SECTION .text
proc Xshutdown ;процедура отвечает за закрытие(удаление) окна
locals none
invoke XFreeGC, dword [hdisplay], dword [hGC]
invoke XDestroyWindow, dword [hdisplay], dword [hwin]
xor eax, eax
endproc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;процедура создания окна
proc Xinitialize, dword t, dword x, dword y, dword w, dword h
locals ;создаем локальные переменные
local hscreen, dword
local hroot, dword
endlocals
invoke XOpenDisplay, 0
or eax, eax
jnz .display_ok
invoke puts, strErrorDisplay
return -1
.display_ok: ; если мы тут то окно создано и ax содержит дескриптор окна
mov dword [hdisplay], eax
invoke XDefaultScreen, dword [hdisplay]
mov dword [var(.hscreen)], eax
invoke XDefaultRootWindow, dword [hdisplay]
mov dword [var(.hroot)], eax
;затем рисуем само окно
;и этот код должен быть в одну строчку
invoke XCreateSimpleWindow, dword [hdisplay], dword [var(.hroot)], dword [argv(.x)], dword [argv(.y)], dword [argv(.w)], dword [argv(.h)], 5, RGB(255,100,50), RGB(25,255,230)
or eax, eax
jne .create_ok
invoke puts, strErrorCreation
return -1
.create_ok:
mov dword [hwin], eax
invoke XSelectInput, dword [hdisplay], dword [hwin], OurInputMask
invoke XStoreName, dword [hdisplay], dword [hwin], dword [argv(.t)]
invoke XMapRaised, dword [hdisplay], dword [hwin]
or eax, eax
jnz .show_ok
invoke puts, strErrorShow
return -1
.show_ok:
invoke XCreateGC, dword [hdisplay], dword [hwin], 0, 0
mov dword [hGC], eax
;цвет текста
invoke XSetForeground, dword [hdisplay], dword [hGC], RGB(0,230,0)
;цвет фона на котором будет текст
invoke XSetBackground, dword [hdisplay], dword [hGC], RGB(0,0,0)
xor eax, eax
endproc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc Xdrawscreen
locals none
invoke XDrawImageString, dword [hdisplay], dword [hwin], dword [hGC], 150, 100, strMessage, lenMessage
endproc
proc Xeventhandler ;функция проверяет нажали ли мы клавишу
locals none
clc ;clear carry
.on_expose:
mov eax, [event] ;помещаем в ах код обработчика событий
cmp eax, Expose ;и сверяем к кодом нажатий клавиш
jnz .on_keypress
;перерисовываем наше окно
invoke Xdrawscreen
jmp .exit
.on_keypress:
cmp eax, KeyPress
jnz .exit
;если клавиша нажата то процедура вернет 1
return 1
.exit:
xor eax, eax
endproc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;наша основная процедура
proc demo
locals none
invoke Xinitialize, strCaption, 10, 200, 400, 200
cmp eax, -1
je .exit
;;; цикл обрабатывающий события окна
.msg_pump:
invoke XNextEvent, dword [hdisplay], event
invoke Xeventhandler
cmp eax, 1
jne .msg_pump
invoke Xshutdown ; вызываем процедуру закрытия окна
xor eax, eax
.exit:
invoke exit, eax ;выход с программы
endproc
Сохраняем файл и заходим в директорию с файлом с помощью терминала. Затем собираем в объектный файл nasm -f elf32 hello.asm. После чего уже делаем исполняемый файл gcc -Wall -s -o hello hello.o -lc -lX11. Все можно запускать наше приложение.
Мы видим на картинки результат кода на ассемблере, который создает оконное приложение с помощью Иксов для Linux.
Оконное приложение для Windows с использованием NASMX
Далее нам нужно взять исходник и поместить также в папку INC, также переместите туда файл windemos.inc который находиться у нас в корне с папками с примерами (Demos). Берем первый исходник с папки Win32/demo1 и помещаем его в папку inc затем собираем его. сначала делаем объектный файл с помощью NASM . К примеру если nasm находиться в корне диска С то в консоли пишем(или в батнике, находиться нужно в папке с кодом) C:\nasm\nasm -f win32 demo1.asm -o demo1.obj -l demo1.lst а затем собираем исходник с помощью Golink, распаковав скачанный архив ECGo.zip также в корне диска С выполняем следующую команда по аналогии с предыдущей: C:\GoAsm\Bin\GoLink.exe /entry _main DEMO1.obj kernel32.dll user32.dll . В итоге получаем исходный exe файл.
В заключение хочу сказать что NASMX упрощает много рутины задач на ассемблере.
Если у Вас возникли вопросы то пишете прям здесь или на форуме .