td win32asm 050.asm
DESCRIPTION
Test department asemblerTRANSCRIPT
td_win32asm_050.asm;==============================================================================; Test Department's WINDOWS 32 BIT x86 ASSEMBLY EXAMPLE's 050;==============================================================================
;==============================================================================; ==> Part 050 : windows high resolution timer;------------------------------------------------------------------------------; Greetings from germany,; the idea here is to use a HIGH RESOLUTION TIMER from the multimedia library.; This timer runs in its own thread !; API "timeSetEvent" / "timeKillEvent" (Mmedia.hlp) is the function call.; This timer is much more exact than a standard windows timer.; This timer could only beat by multimedia applications using MCI services.; In the window procedure (WP1) reacting to a WM_CREATE message I setup a; standard timer (TP0) and the discussed high resolution timer (TP1).; This timer calls a timer procedure (TP1) on the specified delay time.; For example I include a standard windows timer to visualize the difference.; For Fun you can also use an Atomic Radio Clock to check the accuracy ...
;==============================================================================; Assembler directives;------------------------------------------------------------------------------.386 ; specifies the processor our program want run on.Model Flat ,StdCall ; Flat for Win9x (32 Bit), Calling Conventionoption casemap:none ; case sensitive !!!
;==============================================================================; Include all files where API functins resist you want use, set correct path;------------------------------------------------------------------------------include D:\Masm32\include\windows.incincludelib kernel32.libincludelib user32.libincludelib winmm.lib
;==============================================================================; Declaration of used API functions,take a look into WIN32.HLP and *.inc files;------------------------------------------------------------------------------GetModuleHandleA PROTO :DWORDLoadIconA PROTO :DWORD,:DWORDLoadCursorA PROTO :DWORD,:DWORDRegisterClassExA PROTO :DWORDCreateWindowExA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD, :DWORD,:DWORD,:DWORD,:DWORD,:DWORDShowWindow PROTO :DWORD,:DWORDUpdateWindow PROTO :DWORDGetMessageA PROTO :DWORD,:DWORD,:DWORD,:DWORDTranslateMessage PROTO :DWORDDispatchMessageA PROTO :DWORDPostQuitMessage PROTO :DWORDDefWindowProcA PROTO :DWORD,:DWORD,:DWORD,:DWORDExitProcess PROTO :DWORDDestroyWindow PROTO :DWORDSetWindowTextA PROTO :DWORD,:DWORD
Page 1
td_win32asm_050.asmSetTimer PROTO :DWORD,:DWORD,:DWORD,:DWORDKillTimer PROTO :DWORD,:DWORDtimeGetDevCaps PROTO :DWORD,:DWORDtimeSetEvent PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORDtimeKillEvent PROTO :DWORD
;==============================================================================; .const = the constants area starts here,constants are defined and fixed;------------------------------------------------------------------------------.const; - Parameter MAIN WINDOW CallBack Procedure ( API=RegisterClassExA ) -WP1_CallBack equ [ebp+4] ;return addressWP1_hWnd equ [ebp+8] ;handle of window who receives messageWP1_uMsg equ [ebp+12] ;the message numberWP1_wParam equ [ebp+16] ;extra info about the messageWP1_lParam equ [ebp+20] ;extra info about the message
;==============================================================================; .Data = the data area starts here, datas are defined but not fixed;------------------------------------------------------------------------------.DataIconName db "TDIcon",0 ;icon name in rc fileMenuName db "TDMenu",0 ;menu name in rc fileClassName db "TDWinClass",0 ;name of windows classWindowName db "Test Department - http://surf.to/TestD",0;winnameSTATIC_WindowClass db "STATIC",0 ;name of windows classSTATIC_STextWindowName db "Windows Standard Timer in seconds :",0;STATIC_STimeWindowName db "000",0 ;STimeupdate db "000",0 ;STATIC_PTextWindowName db "Windows Precision Timer in seconds :",0;STATIC_PTimeWindowName db "000",0 ;PTimeupdate db "000",0 ;
;==============================================================================; .Data? = the data? area starts here, not defined and not fixed;------------------------------------------------------------------------------.data?STATIC_STexthWnd dd ? ;handle STATIC, standard text windowSTATIC_STimehWnd dd ? ;handle STATIC, standard time windowSTATIC_PTexthWnd dd ? ;handle STATIC, precision text windowSTATIC_PTimehWnd dd ? ;handle STATIC, precision time windowtimerevent1 dd ? ;handle high precision timer
align 4; - WndClassEx Structure ( API=RegisterClassExA ) -cbSize dd ? ;size in bytes of this structurestyle dd ? ;window stylelpfnWndProc dd ? ;address of user proc functioncbclsExtra dd ? ;extra bytes to allocate set to 0cbWndExtra dd ? ;extra bytes class directive, rc filehInstance dd ? ;program handle(API=GetModuleHandleA)hIcon dd ? ;handle of icon (API=LoadIconA)hcursor dd ? ;handle of cursor (API=LoadCursor)
Page 2
td_win32asm_050.asmhbrBackground dd ? ;background color, 0=transparentlpszMenuName dd ? ;name of menu class in resource filelpszClassName dd ? ;name of windows this window classhIconSm dd ? ;iconhandle 0=search in resource file
align 4; - Msg Structure ( API=GetMessageA ) - member POINT = POINT structurehWnd dd ? ;handle of window who receives messagemessage dd ? ;the message numberwParam dd ? ;extra info about the messagelParam dd ? ;extra info about the message time dd ? ;time the message was posted xpt dd ? ;cursor x-position, POINT strucypt dd ? ;cursor x-position, POINT struc
align 4; - TIMECAPS Structure ( API=timeGetDevCaps ) -wPeriodMin dd ? ;TIMER minimum supported resolutionwPeriodMax dd ? ;TIMER maximum supported resolution
;==============================================================================; .CODE = our code area starts here Main = label of our program code;------------------------------------------------------------------------------.CodeMain:
;==============================================================================; Always get your program ID first (API=GetModuleHandleA);------------------------------------------------------------------------------push 0h ;lpModuleHandle, 0=get program handlecall GetModuleHandleA ;- API Function -mov hInstance,eax ;return value in eax=handle of program
;==============================================================================; The API function "RegisterClassExA" registers a window class.; This API needs a "WNDCLASSEX" structure so we fill it with correct values.;------------------------------------------------------------------------------mov cbSize,30h ;size in bytes of WNDCLASSEX structuremov style,3h ;window stylemov lpfnWndProc,OFFSET WP1 ;address of user lpfnWndProc functionmov cbclsExtra,0h ;extra bytes to allocate set to 0mov cbWndExtra,0h ;class directive in rc filemov hbrBackground,2h ;background,1=background(parameter+1)mov lpszMenuName,0h ;menu name in resource file,0=no menumov lpszClassName,OFFSET ClassName;name of windows classmov hIconSm,0h ;iconhandle 0=search in rc file;------------------------------------------------------------------------------; API "LoadIconA" loads an icon defined in the resource file and stores the; handle in the "WNDCLASSEX" structure;------------------------------------------------------------------------------push OFFSET IconName ;icon-string or icon resource idpush hInstance ;our program handlecall LoadIconA ;- API Function -
Page 3
td_win32asm_050.asmmov hIcon,eax ;store handle of newly loaded icon;------------------------------------------------------------------------------; API "LoadCursorA" loads a default system cursor, in this case we must set; hInstance to 0 and lpCursorName to a default system cursor value, here 32512; Then we store the cursor handle in the "WNDCLASSEX" structure;------------------------------------------------------------------------------push 32512 ;lpCursorName, default value in dezimalpush 0h ;hInstance, 0=default system cursorcall LoadCursorA ;- API Function -mov hcursor,eax ;store handle of the cursor;------------------------------------------------------------------------------; Now, after filled the "WNDCLASSEX" structure we call API "RegisterClassEx";------------------------------------------------------------------------------push OFFSET cbSize ;pointer to WNDCLASSEX structurecall RegisterClassExA ;- API Function -
;==============================================================================; API "CreateWindowExA" creates an overlapped, pop-up, or child window with an; extended style. The return value in EAX is the handle of the new window.; This API sends a WM_CREATE message to the window procedure (WP1).;------------------------------------------------------------------------------push 0h ;lpParam, extra pointer data 0=no datapush hInstance ;hInstance, handle of our programpush 0h ;hMenu, handle window menu 0=class menupush 0h ;hWndParent, handle parent window 0=nopush 00000060h ;intnHeight, window height pixelpush 00000140h ;intnWidth, window width pixelpush 00000010h ;inty, vertical position windowpush 00000090h ;intx, horizontal position windowpush 04CA0000h ;dwStyle, look into WIN32.HLPpush OFFSET WindowName ;lpWindowName, pointer to window namepush OFFSET ClassName ;lpClassName, pointer to class namepush 0300h ;dwExStyle, extra window style 0=nocall CreateWindowExA ;- API Function -mov hWnd,eax ;hwnd,return value=handle of window
;==============================================================================; API "ShowWindow" function sets the specified window's show state. ;------------------------------------------------------------------------------push 1h ;nCmdShow, show state 1=SW_SHOWNORMALpush hWnd ;hwnd, handle of windowcall ShowWindow ;- API Function -
;==============================================================================; API "UpdateWindow" updates the area of the specified window by sending a; WM_PAINT message to the window if the window's update region is not empty.;------------------------------------------------------------------------------push hWnd ;hwnd, handle of windowcall UpdateWindow ;- API Function -
LoopGetMessage:;==============================================================================; API "GetMessageA" retrieves a message + places it in the specified structure.
Page 4
td_win32asm_050.asm;------------------------------------------------------------------------------push 0h ;wMsgFilterMax, highest message valuepush 0h ;wMsgFilterMin, lowest message valuepush 0h ;hWnd, handle of window who gets msg.push OFFSET hWnd ;lpMsg, pointer to MSG structurecall GetMessageA ;- API Function -cmp eax,0h ;check if return value=0 (exit)je ExitPrg ;if return value is 0 goto LABEL
;==============================================================================; API "TranslateMessage" translates virtual-key messages in character messages;------------------------------------------------------------------------------push OFFSET hWnd ;lpMSG, pointer to msg structurecall TranslateMessage ;- API Function - keyboard code
;==============================================================================; API "DispatchMessageA" function dispatches a message to a window procedure.;------------------------------------------------------------------------------push OFFSET hWnd ;lpMSG, pointer to msg structurecall DispatchMessageA ;- API Function -jmp LoopGetMessage ;check for message again, goto LABEL
ExitPrg:;==============================================================================; Next we terminate our program (API=ExitProcess);------------------------------------------------------------------------------push hInstance ;push our programm handle to exitcall ExitProcess ;- API Function -
;##############################################################################; The Window Procedure (API=RegisterClassExA) for this registered window.;------------------------------------------------------------------------------WP1:push ebp ;create stack framemov ebp,esp ;pushad ;push all register to the stack
mov eax,WP1_uMsg ;move the message number to eax;==============================================================================; WM_CREATE (value=01h) message received ?;------------------------------------------------------------------------------WP1_uMsg_01h:cmp eax,1h ;check if WM_CREATE message recievedjne WP1_uMsg_02h ;if not goto LABEL;------------------------------------------------------------------------------; API "CreateWindowExA" creates a window with a predefined class name (STATIC).; The return value in EAX is the handle of the new window.;------------------------------------------------------------------------------push 0h ;lpParam, extra pointer data 0=no datapush hInstance ;hInstance, handle of our programpush 0h ;hMenu, handle window menu 0=class menupush WP1_hWnd ;hWndParent, handle parent window 0=nopush 00000016h ;intnHeight, window height pixel
Page 5
td_win32asm_050.asmpush 00000100h ;intnWidth, window width pixelpush 00000008h ;inty, vertical position windowpush 00000008h ;intx, horizontal position windowpush 54000001h ;dwStyle, look WIN32.HLP + windows.incpush OFFSET STATIC_STextWindowName;lpWindowName, pointer to window namepush OFFSET STATIC_WindowClass ;lpClassName, pointer to class namepush 1h ;dwExStyle,look WIN32.HLP + windows.inccall CreateWindowExA ;- API Function -mov STATIC_STexthWnd,eax ;hwnd,return value=handle of window
push 0h ;lpParam, extra pointer data 0=no datapush hInstance ;hInstance, handle of our programpush 0h ;hMenu, handle window menu 0=class menupush WP1_hWnd ;hWndParent, handle parent window 0=nopush 00000016h ;intnHeight, window height pixelpush 00000020h ;intnWidth, window width pixelpush 00000008h ;inty, vertical position windowpush 00000110h ;intx, horizontal position windowpush 54000001h ;dwStyle, look WIN32.HLP + windows.incpush OFFSET STATIC_STimeWindowName;lpWindowName, pointer to window namepush OFFSET STATIC_WindowClass ;lpClassName, pointer to class namepush 1h ;dwExStyle,look WIN32.HLP + windows.inccall CreateWindowExA ;- API Function -mov STATIC_STimehWnd,eax ;hwnd,return value=handle of window
push 0h ;lpParam, extra pointer data 0=no datapush hInstance ;hInstance, handle of our programpush 0h ;hMenu, handle window menu 0=class menupush WP1_hWnd ;hWndParent, handle parent window 0=nopush 00000016h ;intnHeight, window height pixelpush 00000100h ;intnWidth, window width pixelpush 00000020h ;inty, vertical position windowpush 00000008h ;intx, horizontal position windowpush 54000001h ;dwStyle, look WIN32.HLP + windows.incpush OFFSET STATIC_PTextWindowName;lpWindowName, pointer to window namepush OFFSET STATIC_WindowClass ;lpClassName, pointer to class namepush 1h ;dwExStyle,look WIN32.HLP + windows.inccall CreateWindowExA ;- API Function -mov STATIC_PTexthWnd,eax ;hwnd,return value=handle of window
push 0h ;lpParam, extra pointer data 0=no datapush hInstance ;hInstance, handle of our programpush 0h ;hMenu, handle window menu 0=class menupush WP1_hWnd ;hWndParent, handle parent window 0=nopush 00000016h ;intnHeight, window height pixelpush 00000020h ;intnWidth, window width pixelpush 00000020h ;inty, vertical position windowpush 00000110h ;intx, horizontal position windowpush 54000001h ;dwStyle, look WIN32.HLP + windows.incpush OFFSET STATIC_PTimeWindowName;lpWindowName, pointer to window namepush OFFSET STATIC_WindowClass ;lpClassName, pointer to class namepush 1h ;dwExStyle,look WIN32.HLP + windows.inccall CreateWindowExA ;- API Function -
Page 6
td_win32asm_050.asmmov STATIC_PTimehWnd,eax ;hwnd,return value=handle of window;------------------------------------------------------------------------------; timeGetDevCaps function queries the timer device to determine its resolution.; Returned values in the TIMECAPS struc are different from system to system.;------------------------------------------------------------------------------push 8h ;cbtc, size in bytes TIMECAPS structurepush OFFSET wPeriodMin ;ptc, address of a TIMECAPS structurecall timeGetDevCaps ;- API Function -;------------------------------------------------------------------------------; The timeSetEvent function starts a PRECISION timer event. After activated, it; calls the specified callback function. It runs in its own thread ! ;------------------------------------------------------------------------------push 1h ;fuEvent, timer type, TIME_PERIODIC=1hpush 0h ;dwUser, user-supplied callback data push OFFSET TP1 ;lpTimeProc, address callback functionpush wPeriodMin ;uResolution, resolution in mspush 1000 ;uDelay, event delay in millisecondscall timeSetEvent ;- API Function -mov timerevent1,eax ;store handle;------------------------------------------------------------------------------; API "SetTimer" creates a STANDARD timer with the specified time-out value.;------------------------------------------------------------------------------push OFFSET TP0 ;tmprc, address timer procedurepush 1000 ;uTimeout, time-out value millisecondspush 10h ;idTimer, timer identifier, nonzeropush WP1_hWnd ;hwnd, handle of window for timer msg.call SetTimer ;- API Function -jmp WP1_return ;
;==============================================================================; WM_DESTROY (value=02h) message received ?;------------------------------------------------------------------------------WP1_uMsg_02h:cmp eax,2h ;check if value=2h (WM_DESTROY)jne WP1_uMsg_112h ;if not 2h go to LABELcall My_CleanSystem ;- SubRoutine -;------------------------------------------------------------------------------; API "PostQuitMessage" indicates to Windows a request to terminate;------------------------------------------------------------------------------push 0h ;nExitCode, exit code=wParamcall PostQuitMessage ;- API Function -popad ;pop all register back from stackxor eax,eax ;set eax to 0 to exit our programmov esp,ebp ;delete stack framepop ebp ;ret 10h ;return and clear stack
;==============================================================================; WM_SYSCOMMAND (value=112h) message recieved ?;------------------------------------------------------------------------------WP1_uMsg_112h:cmp eax,112h ;check if WM_COMMAND message recievedjne WP1_return ;if not goto label
Page 7
td_win32asm_050.asmmov eax,WP1_wParam ;extra info about the messagecmp eax,0F060h ;SC_CLOSE=0F060h received ?jne WP1_return ;call My_CleanSystem ;- SubRoutine -jmp WP1_return
;==============================================================================; API "DefWindowProcA" calls the window procedure to provide default processing; for any window messages that an application does not process.; This function ensures that every message is processed.; It is called with the same parameters received by the window procedure.;------------------------------------------------------------------------------WP1_return:popad ;pop all register from stackpush WP1_lParam ;extra info about the messagepush WP1_wParam ;extra info about the messagepush WP1_uMsg ;the message numberpush WP1_hWnd ;handle of window who receives messagecall DefWindowProcA ;- API Function -mov esp,ebp ;delete stack framepop ebp ;ret 10h ;return and clear stack;##############################################################################
;##############################################################################; STANDARD TIMER procedure (Win32.hlp) !;------------------------------------------------------------------------------TP0:pushad ;push all register to the stackmov ebx,OFFSET STimeupdate ;update standard timer stringmov ah,30hmov al,[ebx+2]inc alcmp al,39hja Sdigit1mov [ebx+2],aljmp Out_TP0Sdigit1:mov [ebx+2],ahmov al,[ebx+1]inc alcmp al,39hja Sdigit2mov [ebx+1],aljmp Out_TP0Sdigit2:mov [ebx+1],ahmov al,[ebx]inc alcmp al,39hja SdigitResetmov [ebx],aljmp Out_TP0
Page 8
td_win32asm_050.asmSdigitReset:mov [ebx+2],ahmov [ebx+1],ahmov [ebx],ahOut_TP0:;------------------------------------------------------------------------------; API "SetWindowTextA" set's the text of the specified window's title bar.;------------------------------------------------------------------------------push OFFSET STimeupdate ;lpsz, address of stringpush STATIC_STimehWnd ;hwnd, handle of window or controlcall SetWindowTextA ;- API Function -TP0_return:popad ;pop all register back from stackret 10h ;return and clear stack;##############################################################################
;##############################################################################; HIGH RESOLUTION TIMER procedure (Mmedia.hlp) !;------------------------------------------------------------------------------TP1:pushad ;push all register to the stackmov ebx,OFFSET PTimeupdate ;update precision timer stringmov ah,30hmov al,[ebx+2]inc alcmp al,39hja Pdigit1mov [ebx+2],aljmp Out_TP1Pdigit1:mov [ebx+2],ahmov al,[ebx+1]inc alcmp al,39hja Pdigit2mov [ebx+1],aljmp Out_TP1Pdigit2:mov [ebx+1],ahmov al,[ebx]inc alcmp al,39hja PdigitResetmov [ebx],aljmp Out_TP1PdigitReset:mov [ebx+2],ahmov [ebx+1],ahmov [ebx],ahOut_TP1:;------------------------------------------------------------------------------; API "SetWindowTextA" set's the text of the specified window's title bar.;------------------------------------------------------------------------------
Page 9
td_win32asm_050.asmpush OFFSET PTimeupdate ;lpsz, address of stringpush STATIC_PTimehWnd ;hwnd, handle of window or controlcall SetWindowTextA ;- API Function -TP1_return:popad ;pop all register back from stackret 14h ;return and clear stack (14h !!!);##############################################################################
;******************************************************************************; My own subroutine(s) for a compacter code resist here ...;------------------------------------------------------------------------------My_CleanSystem:;------------------------------------------------------------------------------; The timeKillEvent function cancels a specified high precision timer event.;------------------------------------------------------------------------------push timerevent1 ;uTimerID, ID of timer event to cancelcall timeKillEvent ;- API Function -;------------------------------------------------------------------------------; API "KillTimer" destroys the specified standard timer.;------------------------------------------------------------------------------push 10h ;uIDEvent, timer identifierpush WP1_hWnd ;hWnd, handle of window installed timercall KillTimer ;- API Function -ret;******************************************************************************
;==============================================================================; end Main = end of our program code;------------------------------------------------------------------------------end Main ;end of our program code, entry point
;==============================================================================; To create the exe file use this commands with your Microsoft Assembler/Linker;------------------------------------------------------------------------------; ml.exe /c /coff td_win32asm_050.asm ;asm command; rc.exe /v rsrc.rc ;rc command; cvtres.exe /machine:ix86 rsrc.res; link.exe /subsystem:windows td_win32asm_050.obj rsrc.obj ;link command;==============================================================================
Page 10