Using WinAsm and MASM32
Using Invoke with Win32 API functions
New API Functions:
The following screenshot illustrates parts of the WinAsm interface. The sourcecode you type in appears in the code editor pane (left). The explorer pane (right) shows the files which are part of the current project, including asm code, include files, resources, etc. The the "Go All" button (indicated by mouse pointer in the screenshot) will assemble and link your sourcecode and then execute the resulting file . The commands passed to the assembler and linker along with the results are displayed in the output pane (lower).
The 7 lines of code shown above represents the smallest program that will actually assemble, link and execute. It consists of a single RET instruction at the entrypoint which when executed immediately returns control back to Windows. In order to make this into a useful skeleton around which to construct real programs we replace the RET with a call to ExitProcess - the standard API for quitting an app.
In order to start coding, open WinAsm and click the leftmost button on the toolbar. Note that I have the recent projects manager disabled at startup and I use the New Project Wizard Add-In which is great improvement on existing functionality.
Click Next and then Finish. The Standard EXE project type is highlighted by default which sets the assembler and linker options for producing a Win32 GUI executable. WinAsm will prompt you to save the new project file and the new ASM file, after which you will see the empty code editor screen.
Now paste skeleton.asm from the Sourcecode section of this file into the code editor window. Clicking "Go All" will first prompt you to save the project and asm file to a suitable location before building and executing your file. Your code should look like this
We will now analyse this line by line. Most of this code represents directives (instructions to the assembler). There is only one line of actual program code - the call to the API function ExitProcess.
.386- tells MASM to use Intel 80386 instruction set.
.model flat, stdcall - specifies flat memory model and standard call calling convention.
option casemap:none - specifies labels are to be case-sensitive.
include kernel32.inc - tells MASM to process the file named (as if the contents were copied into the sourcecode here)
includelib kernel32.lib - tells linker which import libraries to link with (kernel32.lib in this case).
.data- specifies initialised data (variables which are given a starting value) goes here.
.data? - specifies uninitialised data here (variables which don't yet have a value). Space is allocated when the program is loaded into memory but size of file on disk is not increased.
.const - specifies constants are declared here.
.code- specifies executable code goes here.
start: - arbitrary label to specify beginning of code (note label is followed by ":" when first declared).
invoke ExitProcess,0 - execution starts here, at the instruction immediately below the label specified by the end directive. There is only one instruction here and it calls the ExitProcess API function which is the preferred method of ending a program and returning control to Windows.
end start - marks the end of the module and sets the program entrypoint to the label specified (note label does not need ":" here as it was declared earlier).
The Win32 API
The Windows API (Application Programming Interface) includes the vast collection of data types, constants, functions, and structures used to create applications for the Windows OS. Most of the API functions, including ExitProcess which we used above, are stored in 3 main DLLs:
KERNEL32.DLL - Low level kernel services
GDI32.DLL - Graphics Device Interface: drawing and printing
USER32.DLL - User Interface controls, windows and messaging services
If you use windows API functions in your program, your program has to "import" the functions from the DLLs. Import libraries (.lib files) contain information the linker needs to resolve calls to functions residing in DLLs, so the system can load the specified DLL and locate the exported functions needed when your code is executed. For example, to call the ExitProcess function which resides in kernel32.dll, you must link your code with the import library kernel32.lib. However, the library file is not the only thing you need. An include file (kernel32.inc) is also needed.
Include (.inc) files contain "prototypes" which define the attributes of all functions stored in the DLL of the same name. These can be automatically generated from the library files using the lib2inc utiliy. There is no easy way of generating a library file from a given DLL but luckily most API functions you will require are located in DLLs for which the MASM32 distribution has appropriate library files.
The official Win32 API documentation is written for C and C++ programmers and a typical API function is defined in the following format:
[FONT=Tahoma][SIZE=3]ReturnType FunctionName ( ParamType1 ParamName1, ParamType2 ParamName2,...); [/SIZE][/FONT]
Using the function SetWindowText as an example from the Win32 Programmer's Reference:
The C syntax is easily converted to assembler. The word BOOL is the type of data that the function is expected to return as its result and can be disregarded. HWND is repeated once to represent the size and type of data supplied to the function (really just a DWORD here - these windows data types are all defined in the windows.inc file in C:\masm32\include) and second as the name of the data (here being short for handle to window). This is really much simpler in assembler - the variables or constants which the function needs are PUSHed on the stack and the function is CALLed by name:
[FONT=Tahoma][SIZE=3] PUSH lpString PUSH hWnd CALL SetWindowText [/SIZE][/FONT]
Note that in assembler the parameters are PUSHed on the stack in reverse order compared to the C definition from Win32.hlp, from right to left. This is the STDCALL calling convention which is used almost exclusively in Windows ASM.
Now you know how to use API definitions from Win32.hlp, you can check it for an explanation of any of the API functions we will use during these tutorials.
Including prototypes in your sourcecode has 2 advantages in MASM. The first is that the INVOKE instruction can be used instead of the traditional PUSH/CALL sequence. INVOKE is more compact and parameters do not need to be laid out in reverse order:
[FONT=Tahoma][SIZE=3]INVOKE SetWindowText,hWnd,lpString [/SIZE][/FONT]
The second advantage is that INVOKE allows type-checking so the linker can flag an error if incorrect parameters are passed to the function in your code. Individual function prototypes can be added to the code manually instead of including an entire .inc file but must occur earlier in the code than the INVOKE instructions.
The use of prototypes and invoke can be applied to functions you write yourself as we will see later.
thanks for reading my tutorial more to come on these topics:rolleyes:
Edited by gokuajmes, 26 March 2010 - 07:55 AM.