Assembly programming in Windows
This page is currently extremely limited, and should be expanded upon by someone who knows better how to organize and explain more of this.
Assembly programming in a windows environment is very different than programming for dos, or other lower level environments. You don't have access to interrupts the way you do in dos, or other systems. Instead, you have to go through the Windows API.
The Windows API provides functions for nearly everything you could want to do involving creating and managing windows, performing input and output, and a whole host of other things. To access these functions we must either Invoke or Call them (depending on your assembler and your personal programming style).
This article will assume you know some basic assembly, but will attempt to be as clear as possible in commenting, and in describing any other features of the code.
The sample program below (MASM formatted) here shows what is necessary to open a window:
.386
.model flat,stdcall ;Windows assembly is always in the memory model flat
;And windows always uses the stdcall calling convention
include windows.inc ;This is the Masm32 windows include file, which defines a whole bunch of stuff to make our lives a lot easier
include user32.inc ;This includes function definitions for he functions contained in the user32 library
include kernel32.inc ;This includes function definitions for he functions contained in the kernel32 library
includelib user32.lib ;These includelibs are necessary
includelib kernel32.lib
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD ;This is our main function prototype
.data
ClassName db "MainWinClass",0
AppName db "Main Window",0
.data?
hInstance HINSTANCE ? ;This is the Handle to our program, a handle is a unique identifier windows gives our program
CommandLine LPSTR ? ;This is necessary if you want to be able to get information from command line arguments
.code
start:
invoke GetModuleHandle, NULL ;This will get the handle for our program and store it in our variable
mov hInstance, eax
invoke GetCommandLine ;This will get our command line (optional if you don't want command line arguments)
mov CommandLine,eax
invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT ;SW_SHOWDEFAULT is a windows constant telling it how to show the window
invoke ExitProcess, eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX ;This is our struct containing all the information about our window
LOCAL msg:MSG ;This is the message structure that windows uses to communicate with our window
LOCAL hwnd:HWND ;This is the handle to our Window
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc :We're finished setting things up,giving it the information, now we need to register the window before showing it
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL ;Tell windows to show our newly created window
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CREATE
;
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start