I will introduce the win32 coding and I will focus on the NASM specific part.
Downloadable working examples:
ftp://ftp.szif.hu/pub/demos/tool/w32nasm.zip
http://rs1.szif.hu/~tomcat/win32
There is another tutorial on this topic, called:
"The Win32 NASM Coding Toolkit v0.02 by Gij"
that uses the LCC linker and the resource compiler which comes with LCC.
- Compiling
I'm working with the following free programs in connection with NASM:
- linker: ALINK v1.5 by Anthony A.J. Williams.
- resource compiler: GoRC v0.50b by Jeremy Gordon.
The process of compiling a win32 program involves a number of steps which can
be divided into three main processes: preparing the include files, preparing
the library files, and writing the actual program.
The compiling flow chart
.h -> ? -> .inc
\
.asm -> NASM -> .obj
\
.rc -> GORC -> .res -> ALINK -> .exe
/
.dll -> IMPLIB -> .lib (? means handwork)
2. Include files
The include files (*.inc) must be generated from existing header files (*.h)
that come with win32-compatible C or Pascal compilers. Files needed:
WIN32N.INC (Thanks for the inital MASM version to S.L.Hutchesson).
The compiler will be NASM version 0.97
http://www.cryogen.com/nasm
Usage: nasmw -fobj -w+orphan-labels -pwin32n.inc %1.asm
3. Library files
Files Needed:
WIN32.LIB
The linker will be ALINK
http://www.geocities.com/SiliconValley/Network/4311/#alink
Usage: alink -oPE %1 win32.lib %1.res %2 %3
More lib files can be created with IMPLIB.
Example: IMPLIB DDRAW.DLL
4. Importing API functions
EXTERN MessageBoxA
IMPORT MessageBoxA use32.dll
5. Calling API functions
PUSH UINT MB_OK
PUSH LPCTSTR title1
PUSH LPCTSTR string1
PUSH HWND NULL
CALL [MessageBoxA]
6. WinMain
You don't need to use the name, WinMain:
You must start the program with the label, ..start:
At the begening there is nothing special in the stack, so you should call
GetModuleHandleA for hInstance and GetCommandLineA for the command line.
(Command line consists the full path, the file name and the parameters).
You can exit the program with: RETN
or you should call the ExitProcess function:
PUSH UINT 0 ; the error code
CALL [ExitProcess]
7. Window procedure
There are four parameters on the top of the stack:
PUSH EBP
MOV EBP,ESP
%DEFINE hwnd EBP+8 ;handle of window
%DEFINE message EBP+12 ;message
%DEFINE wParam EBP+16 ;first message parameter
%DEFINE lParam EBP+20 ;second message parameter
You can handle the messages depends on WPARAM [wParam]
and the rest you can pass to DefWindowProcA:
PUSH LPARAM [lParam]
PUSH WPARAM [wParam]
PUSH UINT [message]
PUSH HWND [hwnd]
CALL [DefWindowProcA]
POP EBP
RETN 16
8. Sections
You need a code section:
SECTION CODE USE32 CLASS=CODE
and a data section:
SECTION DATA USE32 CLASS=DATA
You don't need bss section, instead of you should append
every RESB, RESW, RESD, RESQ to the end of the source code.
This zero data not will be included to the exe file.
9. Self modification
You can include your code and data together in one section:
SECTION CODE USE32 CLASS=CODE
In that case you need another object file, with only one line source:
SECTION CODE USE32 CLASS=DATA
ALINK will combine the properties of these two sections.
EXTERN MessageBoxA
EXTERN ExitProcess
SECTION CODE USE32 CLASS=CODE
..start:
PUSH UINT MB_OK
PUSH LPCTSTR title1
PUSH LPCTSTR string1
PUSH HWND NULL
CALL MessageBoxA
PUSH UINT NULL
CALL ExitProcess
SECTION DATA USE32 CLASS=DATA
string1: db 'Hello world!',13,10,0
title1: db 'Hello',0
|