I. Introduction
Win32 applications generally use C language programming, but in situations that need to be deeply programmed, such as Win32 application execution mechanism analysis, virus clearance, encryption decryption, etc., or programs that require high requirements for some speeds, Use the assembly language (or even machine language) to write Win32 applications directly. Win32 applications can use 386 assembly language and protection mode programming, but the implementation mechanism of Win32 applications has certain differences with other 32-bit applications, such as messages. Cycling, dynamic link, etc., Win32 assembly language also has its special programming methods. At present, there are very few information about Win32 assembly language. The assembly language books on the market generally only introduce the DOS real model assembly language and 386 protection model assembly language. Although Jinshan Company's "In-depth Windows Programming" book is introduced to use assembly language Write a WINDOWS application method, unfortunately, the book only introduces Win16 assembly language. In order to make everyone can have a certain understanding of the basic programming method of Win32 assembly language, the author has written this tutorial, which is designed to throw bricks. If this tutorial can lead you into the mysterious Win32 assembly language world, the author is willing to Using this tutorial, the reader is required to have the foundation of the C language to write Win32 applications (Win32SDK programming).
Second, the basic software programming for Win32 assembly language
Perform Win32 assembly language programming, you should prepare the following basic software:
1, MASM 6.11 or later assembler
MASM is Microsoft's assembler, which is the most basic software, with MASM 6.11 or later to assemble Win32 assembly language source programs. However, the Win32 assembly language programming does not have to be full of MASM 6.11, as long as a ml.exe file is OK, Windows 95 DDK ml.exe
For the ML.EXE file with MASM 6.11D in Windows 98 DDK, you can use. Turbo Masm 5.0 is a compiler of Borland, or it can be used to assemble the Win32 assembly language source program, but the Some syntax of TASM is different from MASM, and the Win32 assembly language source program for MASM may need to be modified to use TASM compilation. . All Win32 assembly language source programs in this tutorial are based on MASM.
2, Win32SDK
Perform WIN32 assembly language programming requires the resource compiler (rc.exe) and connectors in Win32SDK, and the introduction library file in Win32SDK (kernel32.lib, user32.lib, gdi32.lib Wait). If there is no Win32SDK, Platform SDK can also be installed in Visual C , and the author uses Visual C 6.0. Borland C 4.0 or more version of Borland C can also be used, just a resource compiler and connector
The file name is different, which is brc.exe (brc32.exe) and tLink.exe (TLINK32.exe), the options are also different, and the Borland C does not support the COFF format OBJ file, and the / COFF option cannot be used when assembled.
3, assembly language editor
A normal text editor for editing the Win32 assembly language source program. Edit, PWB, etc., the editor in the programming language such as Visual C can also, even Word, WPS 97, etc. can edit the word processing software for text files, but the author recommends using AsMedit, this is a dedicated assembly language editor. The effect is very good. Win32 assembly language generally uses the command line mode compilation connection, and it can be integrated in some integration through certain settings.
Connection connections under the environment (PWB, Visual C , AsMedit, etc.), you can also use the NMAKE tool, but only the command line mode is connected in this tutorial, norke tools are not used.
Third, ANSI Character Set API and Unicode Character Set API
There are two different types of APIs related to characters: ANSI character set API and Unicode character set API, corresponding to ANSI characters and Unicode characters, Windows NT support two types of API, Windows 95/98 only support ANSI character set API. Definitions in Windows.h header and other Win32 API
In the header file, all the APIs related to characters have two different definitions, and the ANSI character set API indicates that the Unicode character set API is represented by API name, and use condition compilation. And macro definition automatically uses the corresponding API definition based on the current character set, such as the definition of the getModuleHandle function (including in WinBase.h header file):
WinBaseApi
HModule
WinAPI
GetModuleHandlea (
LPCSTR LPMODULENAME
);
WinBaseApi
HModule
WinAPI
GetModuleHandlew
LPCWSTR LPMODULENAME
);
#ifdef unicode
#define getModuleHandle getModuleHandlew
#ELSE
#define getModuleHandle getModuleHandlea
#ndif //! Unicode
Similar definitions related to characters. This tutorial takes into account the assembly of the assembly language, which will lead to less intuitive, all using the ANSI character set API, which can also ensure compatibility in the Windows 95/98 and Windows NT environments, so many API names and data structures in this tutorial The name is added with "A" characters, and the reader can easily switch to the Unicode character set API.
Fourth, a simple Win32 assembly language program
Readers may feel very headache when I hear four words "assembly language"! The first impression of the assembly language is that a lot of difficulties are difficult to understand, and they are not structured, a large number of labels, unconditional jumping instructions (JMP) and condition jump instructions make it difficult to understand the program; process (Or function) call parameters are not intuitive, either directly use the register to pass parameters, do not meet the structural program design principles; either use the stack pass parameters, and cannot effectively verify the parameter type ... You want Win32 assembly language more troublesome! Fortunately, MASM 6.0 or more versors provide a lot of structured assembly language pseudo-instructions, which can easily implement assembly language structured programming. When you read this tutorial, you may feel that Win32 assembly language is not C is much more troublesome. (If the reader does not understand the assembly language source program in this tutorial, you can look at the help of Masm 6.11) and the C language Win32 programming requires Windows.h header files and other Win32 API definition header file definition constants, data structure, and API Same, Win32 assembly language also needs to include files (INC files) to define constants, data structures, and APIs. However, the author found a long time and did not find a complete Windows.inc file or Win32.inc file (in the Win16 assembly language), the Windows.inc file used for Win16 assembly language, provided in Turbo Masm 5.0. Win32.inc files are not complete, only for the comes with the WAP32 example of the WAP32, and is less compatible with MASM 6.11 (I heard that there is a complete Win32.inc file in NASM, but unfortunately, I don't know if it is not known as Masm 6.11. compatible). The author has to define constants, data structures, and APIs (defined according to Windows.h header files and other Win32 API definitions), but this has brought a lot of benefits - better understanding the programming method of Win32 assembly language and principle. The author wrote a simple Win32 assembly language program that is simple to display: a message box is displayed on the screen. This program only calls two API functions: MessageBox functions and EXITPROCESS functions, the programs are as follows:
Include files (msgbox.inc):
Uint TypedEf DWORD
LPSTR TYPEDEF PTR BYTE
LPCSTR TYPEDEF LPSTR
PVOID TYPEDEF PTR
Handle Typedef Pvoid
HWND TYPEDEF HANDLE
MB_ICONInformation = 00000040H
MB_OK = 0000000000H
Messageboxa Proto Stdcall,: hwnd,: lpcstr,: lpcstr,: uint
EXITPROCESS Proto stdcall,: UINT
Source program (msgbox.asm):
.386P
.Model flat, stdcall
INCLUDE MSGBOX.INC
.Stack 4096
.DATA
Windowtitle Byte 'Msgbox', 0
Message1 Byte 'this is a Simple MessageBox
Win32 Application. ', 0
.Code
_Start:
Invoke Messageboxa, 0, Addr Message1, AddR WindowTitle,
MB_ICONINFORMATION or MB_OK
Invoke EXITPROCESS, 0PUBLIC _START
End
The command to connect the program is as follows:
ML / C / COFF / CP MSGBox.asm
Link / subsystem: windows / entry: _Start msgbox.obj kernel32.lib user32.lib
The / c option in the assembly command represents only assembly, not automatically connected; / coff option represents the OBJ file generated in the COFF format (if you use the Borland connector to use / COFF parameters); / CP option indicates that the identifier is case sensitive. In the connection command / subsystem: windows option indicates that the connector generates a normal Windows executable; / entry: _Start option indicates that the program entry point is the _start identifier. Connect to kernel32.lib and user32.lib when connecting. Run the MSGBox.exe file generated after the assembly connection, a message box will appear on the screen, the title of the message box is "msgbox", the string in the message box is "this is a simple messagebox win32 application.". Win32 assembly language source program should start from .386P directive and .Model flat, StdCall directive, indicate assembler assembly 386 protection mode instruction, and use flat memory mode (Win32 memory mode) and stdcall function call mode (Win32 standard function call) the way). The proto directive definition function prototype (similar to the definition of the function prototype in the C language), can define a function name, call mode, and parameters, invoke directives to call the function defined by the PROTO directive, which can easily deliver parameters and check parameter types. Using the PROTO directive in the msgbox.inc file, use the Invoke directive in the msgbox.asm file to call the API function. It can be seen that the structured assembly language provider provided by the MASM 6.0 or later versatile is greatly simplified by Win32 assembly language programming. This program is not used by a assembly language instruction). This program calls the Messagebox function display message box, call the execution of the EXITPROCESS function termination program, the effect of the EXITPROCESS function is to terminate the current process.
V. Display a window of Win32 assembly language program
The first application that learned Win32SDK programming may be a C language program that displays a window. The author also wrote such a C language program, the program file named Simple.c, the program is as follows:
#include
Static char szwindowclass [] = "simple";
Lresult Callback WndProc (Hwnd Hwnd, Uint Message, WPARAM WPARAM, LPARAM
lparam;
Int WinApi Winmain (Hinstance Hinstance, Hinstance Hprevinstance, LPSTR
LPCMDLINE, INT NSHOWCMD)
{
WNDCLASSEXA WCEX;
Hwnd hwnd;
MSG msg;
IF (! hprevinstance)
{
Wcex.cbsize = sizeof (WNDCLASSEXA);
WCEX.Style = CS_HREDRAW | CS_VREDRAW;
Wcex.cbclsextra = 0;
Wcex.cbWndextra = 0;
WCEX.LPFNWNDPROC = WNDPROC;
WCEX.HINSTANCE = HINSTANCE
WCEX.HICON = Loadicona (Hinstance, IDi_Application);
Wcex.hcursor = loadingcursora (0, IDC_ARROW); wcex.hbrbackground = (Hbrush) (Color_Window 1);
WCEX.LPSZMENUNAME = NULL;
WCEX.LPSZCLASSNAME = SzWindowClass;
Wcex.hiconsm = loading ;;;;;;;;;;;;;;;;;;;;;;;
IF (! RegisterClassexa (& WCEX)) Return False;
}
HWnd = CREATEWINDOWEXA (0, SzWindowClass, "Simple",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
0,0, hinstance, null;
IF (! hwnd) Return False;
ShowWindow (HWND, NSHOWCMD);
UpdateWindow (HWND);
While (GetMessagea (& MSG, 0,0,0))
{
TranslateMessage (& MSG);
DispatchMessagea (& MSG);
}
Return msg.wparam;
}
Lresult Callback WndProc (Hwnd Hwnd, Uint Message, WPARAM WPARAM, LPARAM
lparam)
{
HDC HDC;
Paintstruct PS;
Switch (Message)
{
Case WM_Paint:
HDC = BeginPaint (HWND, & PS);
Endpaint (hwnd, & ps);
Return 0;
Case WM_DESTROY:
PostquitMessage (0);
Return 0;
DEFAULT:
Return DefWindowProca (HWND, MESSAGE, WPARAM, LPARAM);
}
Return -1;
}
This program is basically the same as the general display of a window of a window, just only using an ANSI character set. Now the author uses the WIN32 assembly language program to implement this program, the program is as follows:
Include file (Simple.inc):
Uint TypedEf DWORD
Long TypedEf DWORD
LPSTR TYPEDEF PTR BYTE
LPCSTR TYPEDEF LPSTR
PVOID TYPEDEF PTR
LPVOID TYPEDEF PVOID
Handle Typedef Pvoid
Hinstance Typedef Handle
HWND TYPEDEF HANDLE
HMenu Typedef Handle
HDC Typedef Handle
HgDiobj Typedef Handle
Hicon Typedef Handle
Hcursor Typedef Handle
Hbrush TypedEf Handle
TagWndClassexa Struct
CBSIZE UINT?
STYLE uint?
LPFNWNDPROC DWORD?
CBCLSEXTRA DWORD?
CBWndextra DWORD?
Hinstance DWORD?
HICON DWORD?
HCURSOR DWORD?
HBRBACKGROUND DWORD?
LPSZMENUNAME DWORD?
LPSZCLASSNAME DWORD?
HiconSM DWORD?
TagWndClassexa EndswsWndClassexa TypedEf TagWndClassexa
Tagpoint struct
x long?
Y long?
TagPoint Ends
Point TypedEf TagPoint
Tagmsg struct
MESSAGE UINT?
WPARAM DWORD?
LPARAM DWORD?
Time DWORD?
PT Point <>
Tagmsg Ends
MSG Typedef tagmsg
LPMSG Typedef PTR MSG
TagRect struct
LEFT Long?
Top long?
Right long?
Bottom Long?
TagRect Ends
Rect typef tagRect
Tagpaintstruct Struct
HDC DWORD?
Ferase DWORD?
RcPaint Rect <>
FRESTORE DWORD?
FinCupdate DWORD?
RGBRESERVED BYTE 32 DUP (?)
Tagpaintstruct ends
Paintstruct TypedEf Tagpaintstruct
LPPAINTSTRUCT TYPEDEF PTR PAINTSTRUCT
NULL = 0
True = 0ffffffh
False = 0
SW_SHOWDEFAULT = 10
CS_HREDRAW = 0002H
CS_VREDRAW = 0001H
IDI_Application = 32512
IDC_ARROW = 32512
Color_window = 5
WS_OVERLAPPEDWINDOW = 00cf0000h
CW_USEDEFAULT = 80000000H
WM_PAINT = 000FH
WM_DESTROY = 0002H
GetModuleHandlea Proto stdcall,: LPCSTR
Getcommandlinea Proto stdcall
EXITPROCESS Proto stdcall,: UINT
Loadicona Proto Stdcall,: Hinstance,: LPCSTR
Loadcursora Proto Stdcall,: Hinstance,: LPCSTR
RegisterClassexa Proto stdcall,: PTR WNDCLASSEXA
CreateWindowexa Proto Stdcall,: DWORD,: LPCSTR,: LPCSTR,: DWORD,
DWORD,: DWORD,: DWORD,: DWORD,: HWND,: HMENU,: HINSTANCE,: LPVOID
ShowWindow Proto Stdcall,: hWnd,: DWORD
UpdateWindow Proto stdcall,: hwnd
GetMessagea Proto stdcall,: lpmsg,: hwnd,: uint,: uint
TranslateMessage Proto stdcall,: PTR MSG
DispatchMessagea Proto stdcall,: PTR MSG
Beginpaint Proto stdcall,: hWnd,: LPPAINTSTRUCT
Endpaint Proto stdcall,: hWnd,: Ptr Paintstruct
PostquitMessage Proto Stdcall,: DWORD
DefWindowProca Proto Stdcall,: HWnd,: Uint,: DWORD,: DWORD Source (Simple.asm):
.386P
.Model flat, stdcall
INCLUDE SIMPLE.INC
Winmain Proto Stdcall,: Hinstance,: Hinstance,: LPSTR ,:
DWORD
.Stack 4096
.DATA
WindowClass Byte 'Simple', 0
Windowtitle Byte 'Simple', 0
Hinst1 hinstance 0
LPCMDLINE1 LPSTR 0
.Code
_Start:
Invoke getModuleHandlea, NULL
Mov Hinst1, EAX
Invoke getcommandlinea
Mov LPCMDLINE1, EAX
Invoke Winmain, Hinst1, Null, Lpcmdline1, SW_Showdefault
Invoke EXITPROCESS, EAX
Winmain Proc Hinst: Hinstance, Hprevinst: Hinstance, LPCMDLINE: LPSTR,
NShowCMD: DWORD
Local Wcex: WNDCLASSEXA
Local hwnd: hwnd
Local MSG: MSG
.IF! HPREVINST
Mov wcex.cbsize, sizeof wndclassexa
Mov Wcex.Style, CS_HREDRAW or CS_VREDRAW
MOV WCEX.CBCLSEXTRA, 0
Mov wcex.cbwndextra, 0
MOV WCEX.LPFNWNDPROC, OFFSET WNDPROC
Mov Eax, Hinst
Mov wcex.hinstance, EAX
Invoke Loadicona, Hinst, IDi_Application
Mov Wcex.hicon, EAX
Invoke loadcursora, 0, IDC_ARROW
Mov Wcex.hcursor, EAX
MOV WCEX.HBRBACKGROUND, Color_Window 1
MOV WCEX.LPSZMENUNUNAME, NULL
MOV WCEX.LPSZCLASSNAME, OFFSET WINDOWCLASS
Invoke Loadicona, Hinst, IDi_Application
Mov wcex.hiconsm, EAX
Invoke RegisterClassexa, Addr WCEX
.IF! EAX
Mov Eax, False
RET
.Endif
.Endif
Invoke CreateWindowexa, 0, AddR WindowClass, AddR Windowtitle,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, 0, 0, HINST, NULL
MOV HWND, EAX
.IF! EAX
Mov Eax, False
RET
.Endif
Invoke ShowWindow, Hwnd, NShowCMD
Invoke UpdateWindow, HWnd
.While true
Invoke GetMessagea, Addr MSG, 0,0,0
.Break .if! EAX
Invoke TranslateMessage, Addr MSG
Invoke DispatchMessagea, Addr MSG
.Endw
Mov Eax, Msg.wParam
RET
Winmain ENDP
WndProc Proc Hwnd: HWnd, Message: Uint, WParam: DWORD, LPARAM: DWORDLOCAL HDC: HDC
Local PS: PaintStruct
.IF message == wm_paint
Invoke Beginpaint, HWnd, Addr PS
MOV HDC, EAX
Invoke endpaint, hwnd, addr ps
MOV EAX, 0
RET
.ELSEIF message == WM_DESTROY
Invoke PostquitMessage, 0
MOV EAX, 0
RET
.Lse
Invoke DefWindowProca, Hwnd, Message, WParam, LPARAM
RET
.Endif
MOV Eax, 0FFFFFFFH
RET
WNDPROC ENDP
Public _Start
End
The command to connect the program is as follows:
ML / C / COFF / CP SIMPLE.ASM
Link / subsystem: windows / entry: _Start Simple.obj kernel32.lib user32.lib
GDI32.LIB
The Simple.exe file generated after the assembly is run, and a standard window will appear on the screen, and the title of the window is "Simple". Readers who have learned Win32SDK know that the entry point of the Win32 application is a winmain function. In fact, the WinMain function is called by the initialization and end code of the C language, and the true entry point of the Win32 application is nothing difference. Both the application starting point specified in the file header. Win32 assembly language has no C language initialization and end code, must write initialization and end code calls.
The prototype of the Winmain function (process), the WinMain function is:
Int WinApi Winmain (Hinstance Hinstance, Hinstance Hprevinstance, LPSTR
LPCMDLINE, INT NSHOWCMD);
Winmain functions have 4 parameters, namely:
Hinstance-- The handle of the current instance can be obtained by calling the getModuleHandle function.
HPREVINSTANCE - the handle of the previous instance of the application, the other instance of the application does not have an application in the current address space in Win32, which is usually set to NULL (providing this parameter is just easy to port Win16 application source program).
LPCMDLINE - command line parameters can be obtained by calling the getcommandline function. The NSHOWCMD - the display status of the main window can be set to sw_showdefault. The initialization and end code of this program are as follows:
Invoke getModuleHandlea, NULL
Mov Hinst1, EAX
Invoke getcommandlinea
Mov LPCMDLINE1, EAX
Invoke Winmain, Hinst1, Null, Lpcmdline1, SW_Showdefault
Invoke EXITPROCESS, EAX
Win32 standard function call mode, function return value returns via the EAX register. The initialization and end code of this program is simple, just call the getModuleHandle function to obtain the handle of the application's current instance, call the getcommandline function to obtain the command line parameter, then call the WinMain function (process), the winmain function returns the execution of the EXITPROCESS function termination program . Comparing this program with Simple.c programs, you can see that the program structure is very similar, and this program uses a large number of structural assembly language providers provided by MASM 6.0 or higher, not much trouble than C language. 6. Use resources in Win32 assembly language programs
Resources are very important in Win32 applications, and the author wrote a C language program that uses resources, which implements the menu and a "About" dialog, the program is as follows:
Source program (generic.c):
#include
#include "resource.h"
Static hinstance hinst;
Static char szwindowclass [] = "generic";
Lresult Callback WndProc (Hwnd Hwnd, Uint Message, WPARAM WPARAM, LPARAM
lparam;
Bool Callback AboutdlgProc (HWND HDLG, Uint Message, WParam WPARAM, LPARAM
lparam;
Int WinApi Winmain (Hinstance Hinstance, Hinstance Hprevinstance, LPSTR
LPCMDLINE, INT NSHOWCMD)
{
WNDCLASSEXA WCEX;
Hwnd hwnd;
MSG msg;
Hinst = hinstance;
IF (! hprevinstance)
{
Wcex.cbsize = sizeof (WNDCLASSEXA);
WCEX.Style = CS_HREDRAW | CS_VREDRAW;
Wcex.cbclsextra = 0;
Wcex.cbWndextra = 0;
WCEX.LPFNWNDPROC = WNDPROC;
WCEX.HINSTANCE = HINSTANCE
WCEX.HICON = Loadicona (Hinstance, IDi_Application);
WCEX.HCURSOR = loadingcursora (0, IDC_ARROW);
Wcex.hbrbackground = (Hbrush) (Color_Window 1);
WCEX.LPSZMENUNAME = MakeintResource (IDR_MAINMENU);
WCEX.LPSZCLASSNAME = SzWindowClass;
Wcex.hiconsm = loading ;;;;;;;;;;;;;;;;;;;;;;;
IF (! RegisterClassexa (& WCEX)) Return False;
}
HWnd = CreateWindowexa (0, SzWindowClass, "Generic",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
0,0, hinstance, null;
IF (! hwnd) Return False;
ShowWindow (HWND, NSHOWCMD);
UpdateWindow (HWND);
While (GetMessagea (& MSG, 0,0,0))
{
TranslateMessage (& MSG); DispatchMessagea (& MSG);
}
Return msg.wparam;
}
Lresult Callback WndProc (Hwnd Hwnd, Uint Message, WPARAM WPARAM, LPARAM
lparam)
{
HDC HDC;
Paintstruct PS;
Switch (Message)
{
Case WM_COMMAND:
Switch (loword (wparam))
{
Case idm_exit:
SendMessagea (HWND, WM_CLOSE, 0, 0);
Return 0;
Case IDM_About:
Dialogboxparama (Hinst, MakeintResource (IDD_ABOUT),
HWnd, (DLGPROC) AboutdlgProc, 0);
Return 0;
DEFAULT:
Return DefWindowProca (Hwnd, Message, WPARAM, LPARAM)
;
}
Case WM_Paint:
HDC = BeginPaint (HWND, & PS);
Endpaint (hwnd, & ps);
Return 0;
Case WM_DESTROY:
PostquitMessage (0);
Return 0;
DEFAULT:
Return DefWindowProca (HWND, MESSAGE, WPARAM, LPARAM);
}
Return -1;
}
Bool Callback AboutdlgProc (HWND HDLG, Uint Message, WParam WPARAM, LPARAM
lparam)
{
Switch (Message)
{
Case WM_INITDIALOG:
Return True;
Case WM_COMMAND:
IF ((WPARAM) == iDok || (loword (wparam) == idcancel)
{
EndDialog (HDLG, LOWORD (WPARAM));
Return True;
}
Return False;
DEFAULT:
Return False;
}
}
Resource source file (Generic.rc, established using Visual C 6.0):
// Microsoft Developer Studio Generated Resource Script.
//
#include "resource.h"
#define apstudio_readonly_symbols
/
//
// generated from the textinclude 2 resource.
//
#include "afxres.h"
/
#undef apstudio_readonly_symbols
/
// Chinese (p.r.c.) Resources
#if! defined (AFX_RESOURCE_DLL) || Defined (AFX_TARG_CHS)
#ifdef _win32
Language lang_chinese, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page (936)
#ENDIF / / / WIN32
/
//
// menu
//
IDR_MainMenu Menu Discardable
Begin
Popup "& file"
Begin
MenuItem "& exit", IDM_exit
End
Popup "& Help"
Begin
Menuitem "& About ...", IDM_ABOUT
End
End
#ifdef apstudio_invoke
/
//
// textinclude
//
1 TextInclude Discardable
Begin
"resource.h / 0"
End
2 TEXTINCLUDE DISCARDABLE
Begin
"#include" "AfxRes.h" "/ r / n"
"/ 0"
End
3 TEXTINCLUDE DISCARDABLE
Begin
"/ r / n"
"/ 0"
End
#ENDIF // APSTUDIO_INVOKED
/
//
// Dialog
//
IDD_ABOUT DIALOG DISCARDABLE 0, 0, 92, 65
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
Caption "About"
Font 9, "Song"
Begin
LTEXT "Generic V1.0", IDC_STATIC1, 20, 10, 50, 10
Defpushbutton "OK", IDOK, 20, 40, 50, 15
End
/
//
// DesignInfo
//
#ifdef apstudio_invoke
Guidelines DesignInfo Discardable
Begin
IDD_ABOUT, DIALOG
Begin
Leftmargin, 7
Rightmargin, 85
TopMargin, 7
Bottommargin, 58
End
End
#ENDIF // APSTUDIO_INVOKED
#ENDIF // Chinese (p.r.c.) Resources
/
#ifndef apstudio_invokeed
/
//
// generated from the textinclude 3 resource.
//
/
#ENDIF // NOT APSTUDIO_INVOKED
Resource header file (RESOURCE.H, Visual C 6.0 Automatic Establishment):
// {{NO_DEPENDENCIES}}
// Microsoft Developer Studio Generated Include File.
// use by generic.rc
//
#define idR_mainMenu 101
#define IDD_ABOUT 102
#define IDC_STATIC1 1000
#define idm_exit 40001
#define idm_about 40002
// Next Default Values for New Objects
//
#ifdef apstudio_invoke
#ifndef apstudio_readonly_symbols
#define _APS_Next_Resource_Value 103
#define _APS_Next_Command_Value 40003
#define _APS_Next_Control_Value 1001
#define _aps_next_symed_value 101 # Endif
#ENDIF
This program is basically the same as the Generic program in general Win32 programming data, just only using an ANSI character set.
Now the author uses the WIN32 assembly language program to implement this program, the program is as follows:
Include file (generic.inc):
Uint TypedEf DWORD
Long TypedEf DWORD
LPSTR TYPEDEF PTR BYTE
LPCSTR TYPEDEF LPSTR
PVOID TYPEDEF PTR
LPVOID TYPEDEF PVOID
Handle Typedef Pvoid
Hinstance Typedef Handle
HWND TYPEDEF HANDLE
HMenu Typedef Handle
HDC Typedef Handle
HgDiobj Typedef Handle
Hicon Typedef Handle
Hcursor Typedef Handle
Hbrush TypedEf Handle
TagWndClassexa Struct
CBSIZE UINT?
STYLE uint?
LPFNWNDPROC DWORD?
CBCLSEXTRA DWORD?
CBWndextra DWORD?
Hinstance DWORD?
HICON DWORD?
HCURSOR DWORD?
HBRBACKGROUND DWORD?
LPSZMENUNAME DWORD?
LPSZCLASSNAME DWORD?
HiconSM DWORD?
TagWndClassexa Ends
WNDCLASSEXA TYPEDEF TAGWNDCLASSEXA
Tagpoint struct
x long?
Y long?
TagPoint Ends
Point TypedEf TagPoint
Tagmsg struct
MESSAGE UINT?
WPARAM DWORD?
LPARAM DWORD?
Time DWORD?
PT Point <>
Tagmsg Ends
MSG Typedef tagmsg
LPMSG Typedef PTR MSG
TagRect struct
LEFT Long?
Top long?
Right long?
Bottom Long?
TagRect Ends
Rect typef tagRect
Tagpaintstruct Struct
HDC DWORD?
Ferase DWORD?
RcPaint Rect <>
FRESTORE DWORD?
FinCupdate DWORD?
RGBRESERVED BYTE 32 DUP (?)
Tagpaintstruct ends
Paintstruct TypedEf Tagpaintstruct
LPPAINTSTRUCT TYPEDEF PTR PAINTSTRUCT
NULL = 0
True = 0ffffffh
False = 0
SW_SHOWDEFAULT = 10
CS_HREDRAW = 0002H
CS_VREDRAW = 0001H
IDI_Application = 32512
IDC_ARROW = 32512
Color_window = 5
WS_OVERLAPPEDWINDOW = 00cf0000HCW_USEDEFAULT = 80000000H
WM_COMMAND = 0111h
WM_CLOSE = 0010H
WM_PAINT = 000FH
WM_DESTROY = 0002H
WM_INITDIALOG = 0110h
IDOK = 1
IDCANCEL = 2
GetModuleHandlea Proto stdcall,: LPCSTR
Getcommandlinea Proto stdcall
EXITPROCESS Proto stdcall,: UINT
Loadicona Proto Stdcall,: Hinstance,: LPCSTR
Loadcursora Proto Stdcall,: Hinstance,: LPCSTR
RegisterClassexa Proto stdcall,: PTR WNDCLASSEXA
CreateWindowexa Proto Stdcall,: DWORD,: LPCSTR,: LPCSTR,: DWORD,
DWORD,: DWORD,: DWORD,: DWORD,: HWND,: HMENU,: HINSTANCE,: LPVOID
ShowWindow Proto Stdcall,: hWnd,: DWORD
UpdateWindow Proto stdcall,: hwnd
GetMessagea Proto stdcall,: lpmsg,: hwnd,: uint,: uint
TranslateMessage Proto stdcall,: PTR MSG
DispatchMessagea Proto stdcall,: PTR MSG
SendMessagea Proto Stdcall,: HWnd,: Uint,: DWORD,: DWORD
Dialogboxparama Proto Stdcall,: Hinstance,: lpcstr,: hWnd,: DWORD,
DWORD
Beginpaint Proto stdcall,: hWnd,: LPPAINTSTRUCT
Endpaint Proto stdcall,: hWnd,: Ptr Paintstruct
PostquitMessage Proto Stdcall,: DWORD
DefWindowProca Proto Stdcall,: HWnd,: Uint,: DWORD,: DWORD
Enddialog Proto Stdcall,: hWnd,: DWORD
Resource contains files (resource.inc):
IDR_MAINMENU = 101
IDD_ABOUT = 102
IDC_STATIC1 = 1000
IDM_EXIT = 40001
IDM_ABOUT = 40002
Source program (Generic.asm):
.386P
.Model flat, stdcall
Include generic.inc
Include resource.inc
Winmain Proto Stdcall,: Hinstance,: Hinstance,: LPSTR ,:
DWORD
.Stack 4096
.DATA
WindowClass Byte 'Generic', 0
WINDOWTILE BYTE 'Generic', 0
Hinst1 hinstance 0
LPCMDLINE1 LPSTR 0
.Code
_Start:
Invoke getModuleHandlea, NULL
Mov Hinst1, EAX
Invoke getcommandlineamov LPCMDLINE1, EAX
Invoke Winmain, Hinst1, Null, Lpcmdline1, SW_Showdefault
Invoke EXITPROCESS, EAX
Winmain Proc Hinst: Hinstance, Hprevinst: Hinstance, LPCMDLINE: LPSTR,
NShowCMD: DWORD
Local Wcex: WNDCLASSEXA
Local hwnd: hwnd
Local MSG: MSG
.IF! HPREVINST
Mov wcex.cbsize, sizeof wndclassexa
Mov Wcex.Style, CS_HREDRAW or CS_VREDRAW
MOV WCEX.CBCLSEXTRA, 0
Mov wcex.cbwndextra, 0
MOV WCEX.LPFNWNDPROC, OFFSET WNDPROC
Mov Eax, Hinst
Mov wcex.hinstance, EAX
Invoke Loadicona, Hinst, IDi_Application
Mov Wcex.hicon, EAX
Invoke loadcursora, 0, IDC_ARROW
Mov Wcex.hcursor, EAX
MOV WCEX.HBRBACKGROUND, Color_Window 1
MOV WCEX.LPSZMENUNUNUNAME, IDR_MAINMENU AND 0000FFFH
MOV WCEX.LPSZCLASSNAME, OFFSET WINDOWCLASS
Invoke Loadicona, Hinst, IDi_Application
Mov wcex.hiconsm, EAX
Invoke RegisterClassexa, Addr WCEX
.IF! EAX
Mov Eax, False
RET
.Endif
.Endif
Invoke CreateWindowexa, 0, AddR WindowClass, AddR Windowtitle,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, 0, 0, HINST, NULL
MOV HWND, EAX
.IF! EAX
Mov Eax, False
RET
.Endif
Invoke ShowWindow, Hwnd, NShowCMD
Invoke UpdateWindow, HWnd
.While true
Invoke GetMessagea, Addr MSG, 0,0,0
.Break .if! EAX
Invoke TranslateMessage, Addr MSG
Invoke DispatchMessagea, Addr MSG
.Endw
Mov Eax, Msg.wParam
RET
Winmain ENDP
WndProc Proc HWND: HWND, Message: Uint, WParam: DWORD, LPARAM: DWORD
Local HDC: HDC
Local PS: PaintStruct
.IF message == WM_COMMAND
Mov Eax, WPARAM
.IF AX == idm_exit
Invoke SendMessagea, Hwnd, WM_Close, 0,0
MOV EAX, 0
RET
.ELSEIF AX == IDM_ABOUT
MOV EBX, Offset Aboutdlgproc
Invoke Dialogboxparama, Hinst1, IDD_ABOUT AND
0000ffffh, hwnd, ebx, 0
MOV EAX, 0
RET
.Lse
Invoke DefWindowProca, HWnd, Message, WPARAM,
lparam
RET
.Endif.elseif message == wm_paint
Invoke Beginpaint, HWnd, Addr PS
MOV HDC, EAX
Invoke endpaint, hwnd, addr ps
MOV EAX, 0
RET
.ELSEIF message == WM_DESTROY
Invoke PostquitMessage, 0
MOV EAX, 0
RET
.Lse
Invoke DefWindowProca, Hwnd, Message, WParam, LPARAM
RET
.Endif
MOV Eax, 0FFFFFFFH
RET
WNDPROC ENDP
AboutDLGProc Proc HDLG: HWnd, Message: Uint, WParam: DWORD, LPARAM: DWORD
.IF Message == WM_INITDIALOG
Mov Eax, True
RET
.ELSEIF message == WM_COMMAND
Mov Eax, WPARAM
.IF (AX == IDOK) || (AX == IDCancel)
Invoke EndDialog, HDLG, AX
Mov Eax, True
RET
.Endif
Mov Eax, False
RET
.Lse
Mov Eax, False
RET
.Endif
Mov Eax, False
RET
AboutdlgProc ENDP
Public _Start
End
The command to connect the program is as follows:
ML / C / COFF / CP generic.asm
RC generic.rc
Link / subsystem: windows / entry: _Start generic.obj generic.res kernel32.
LIB User32.lib GDI32.LIB
The generic.exe file generated after the assembly connection is run, and a window with a menu will appear. The title of the window is "generic", the menu has two main menu items, respectively "File" and "Help", select The "EXIT" menu item under the "File" menu item can exit the program and select the "About" menu item under the "Help" menu item to display the "About" dialog. This program is very similar to the Simple.c program. The method of using resources in Win32 assembly language programs is also different from C language programs, which can generate resource source files and resource header files with resource editing tools, and then use the resource compiler. Compile the resource source file, connect the generated resource file (RES file) to the target file generated by the assembler and the introduction library file (resource header files need to be ported to assembly language), establish a resource containing files).
The essence of the MakeintResource macro in the C language program is to clear the high level (not used) of the resource identifier value, and then forcibly convert to a character pointer, and the resource identifier value and 0000FFFFH will be used as an operation in the Win32 assembly language program.
Seven, console Win32 assembly language program
Readers who have learned Win32SDK programming must know the console Win32 application, the console Win32 application runs under the console (MS-DOS window), is very similar to the C language program under DOS, the program entry point is the main function, the standard The C language I / O function performs I / O, or the API can also be called. In fact, the console Win32 application is not essentially different from the ordinary Win32 application. The standard C language I / O function actually calls the API, and I / O on the console. The console Win32 assembly language program has certain differences and C language programs that need to obtain the console I / O handle, then use the console I / O handle to perform I / O (similar to the file handle I / O), the author takes MASM 6.11 The console Win32 assembly language program instance (HELLO.ASM) is as follows: .386
.Model flat, stdcall
STD_OUTPUT_HANDLE EQU -11
Getstdhandle Proto near32 stdcall,
NSTDHANDLE: DWORD
Writefile Proto near32 stdcall,
Hfile: DWORD, LPBUFFER: NEAR32, NNUMBEROFBYTESTOWRITE: DWORD,
LPNUMBEROFBYTESWRITTEN: NEAR32, LPOVERLAPPED: NEAR32
EXITPROCESS proto near32 stdcall,
DWEXITCODE: DWORD
.Stack 4096
.DATA
MSG DB "Hello, World.", 13, 10
Written DD 0
HSTDOUT DD 0
.Code
_Start:
Invoke getstdhandle,
STD_OUTPUT_HANDLE; Standard Output Handle
MOV HSTDOUT, EAX
Invoke Writefile,
HSTDOUT, File Handle for Screen
NEAR32 PTR MSG ,; Address of String
Lengthof msg, longth of string
NEAR32 PTR Written,; bytes Written
Overlapped mode
Invoke EXITPROCESS,
0; Result Code for Parent Process
Public _Start
End
The command to connect the program is as follows:
ML / C / COFF / CP Hello.asm
Link / subsystem: console / entry: _Start Hello.obj kernel32.lib
In the connection command / subsystem: console option indicates that the connector generates a console Win32 application. The Hello.exe file generated after the compilation connection is run under the MS-DOS window (console), which will display "Hello, World." Strings like the MS-DOS program. This program calls the getStdHandle function to obtain the standard console output device handle, then call the WriteFile function to output the device handle string to the standard console, complete the console string output, and finally call the execution of the EXITPROCESS function termination program.
Eight, conclude