📄 exdll.asm
字号:
; #########################################################################
;
; This demo show how to use an external DLL when you have no IMPORT
; library to use for its functions. It uses LoadLibrary() and
; GetProcAddress() to get the addresses of the functions. It shows 2
; ways of calling the functions, a seperate procedure for each function
; call so that the invoke syntax can be used and a direct call to the
; function where stack overhead interferes with speed critical code.
;
; The code to use the DLL functions is in the WndProc procedure and is
; processed in the WM_COMMAND message. The seperate procedures for each
; function call are at the end of the file.
;
; #########################################################################
.386
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include ExDLL.inc ; local includes for this file
; -----------------------------------
; Normal prototypes for DLL functions
; -----------------------------------
Sqrt PROTO:DWORD
ShowValue PROTO:DWORD
Add_1 PROTO:DWORD
Minus_1 PROTO:DWORD
; #########################################################################
.code
start:
invoke LoadLibrary,ADDR DLLname ; Load the DLL and get its handle
mov hDLL, eax
invoke LoadProcs,hDLL ; Get the addresses of the procedures
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke FreeLibrary,hDLL ; Free the DLL after use
invoke ExitProcess,eax
; #########################################################################
LoadProcs proc hLibrary:DWORD
; --------------------------------------------------------------
; This gets the address of each procedure so it can be used with
; the "call" mnemonic in either the seperate procedures for each
; function or for direct manual function usage.
; --------------------------------------------------------------
invoke GetProcAddress,hLibrary,ADDR p1name
mov lpSqrt, eax
invoke GetProcAddress,hLibrary,ADDR p2name
mov lpShowValue, eax
invoke GetProcAddress,hLibrary,ADDR p3name
mov lpAdd_1, eax
invoke GetProcAddress,hLibrary,ADDR p4name
mov lpMinus_1, eax
ret
LoadProcs endp
; #########################################################################
WinMain proc hInst :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD
;====================
; Put LOCALs on stack
;====================
LOCAL wc :WNDCLASSEX
LOCAL msg :MSG
LOCAL Wwd :DWORD
LOCAL Wht :DWORD
LOCAL Wtx :DWORD
LOCAL Wty :DWORD
LOCAL ref :DWORD
;==================================================
; Fill WNDCLASSEX structure with required variables
;==================================================
invoke LoadIcon,hInst,500 ; icon ID
mov hIcon, eax
szText szClassName,"ExDLL_Class"
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW \
or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, offset WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
m2m wc.hInstance, hInst
mov wc.hbrBackground, COLOR_BTNFACE+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, offset szClassName
m2m wc.hIcon, hIcon
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor, eax
m2m wc.hIconSm, hIcon
invoke RegisterClassEx, ADDR wc
;================================
; Centre window at following size
;================================
mov Wwd, 500
mov Wht, 350
invoke GetSystemMetrics,SM_CXSCREEN
invoke TopXY,Wwd,eax
mov Wtx, eax
invoke GetSystemMetrics,SM_CYSCREEN
invoke TopXY,Wht,eax
mov Wty, eax
invoke CreateWindowEx,WS_EX_LEFT,
ADDR szClassName,
ADDR szDisplayName,
WS_OVERLAPPED or WS_SYSMENU,
Wtx,Wty,Wwd,Wht,
NULL,NULL,
hInst,NULL
mov hWnd,eax
invoke ShowWindow,hWnd,SW_SHOWNORMAL
invoke UpdateWindow,hWnd
;===================================
; Loop until PostQuitMessage is sent
;===================================
StartLoop:
invoke GetMessage,ADDR msg,NULL,0,0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp StartLoop
ExitLoop:
return msg.wParam
WinMain endp
; #########################################################################
WndProc proc hWin :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD
LOCAL ref :DWORD
.if uMsg == WM_COMMAND
.if wParam == 500
; ----------------------------------
; Use the DLL functions with the
; protection of the "invoke" syntax.
; ----------------------------------
mov eax, 16 ; put a number in eax
invoke Sqrt,eax ; get its square root
invoke Minus_1,eax ; subtract 1 from it
invoke Add_1,eax ; add 1 to it
mov ref, eax
invoke ShowValue,ref ; display 1st result
.elseif wParam == 501
; ----------------------------------
; Call the "Add_1" function manually
; to avoid the extra stack overhead.
; ----------------------------------
mov ref, 0
@@:
push ref
call lpAdd_1 ; call "Add_1" DLL function 1 million times
mov ref, eax
cmp ref, 1000000
jne @B
invoke ShowValue,ref ; display 2nd result
.endif
.elseif uMsg == WM_CREATE
.data
butn1 db "Test Invoked functions",0
butn2 db "Manually call function",0
.code
invoke PushButton,ADDR butn1,hWin,20,20,200,25,500
invoke PushButton,ADDR butn2,hWin,20,60,200,25,501
.elseif uMsg == WM_CLOSE
.elseif uMsg == WM_DESTROY
invoke PostQuitMessage,NULL
return 0
.endif
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
WndProc endp
; ########################################################################
TopXY proc wDim:DWORD, sDim:DWORD
shr sDim, 1 ; divide screen dimension by 2
shr wDim, 1 ; divide window dimension by 2
mov eax, wDim ; copy window dimension into eax
sub sDim, eax ; sub half win dimension from half screen dimension
return sDim
TopXY endp
; #########################################################################
Sqrt proc value:DWORD
push value
call lpSqrt ; return value is in eax
ret
Sqrt endp
; ########################################################################
ShowValue proc value:DWORD
push value
call lpShowValue
ret
ShowValue endp
; ########################################################################
Add_1 proc value:DWORD
push value
call lpAdd_1 ; return value is in eax
ret
Add_1 endp
; ########################################################################
Minus_1 proc value:DWORD
push value
call lpMinus_1 ; return value is in eax
ret
Minus_1 endp
; ########################################################################
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -