📄 lion-tutorial12.htm
字号:
<html>
<head>
<link rel="stylesheet" href="../../asm.css">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Iczelion's win32 asm tutorial</title>
</head>
<body bgcolor="#FFFFFF" background="../../images/back01.jpg">
<p align="center">Tutorial 12: Memory Management and File I/O</p>
<hr size="1">
We will learn the rudimentary of memory management and file i/o operation in this
tutorial. In addition we'll use common dialog boxes as input-output devices.
<p>Download the example <a href="files/tut12.zip">here</a>.
<h3> Theory:</h3>
Memory management under Win32 from the application's point of view is quite simple
and straightforward. Each process owns a 4 GB memory address space. The memory
model used is called flat memory model. In this model, all segment registers (or
selectors) point to the same starting address and the offset is 32-bit so an application
can access memory at any point in its own address space without the need to change
the value of selectors. This simplifies memory management a lot. There's no "near"
or "far" pointer anymore. <br>
Under Win16, there are two main categories of memory API functions: Global and
Local. Global-type API calls deal with memory allocated in other segments thus
they're "far" memory functions. Local-type API calls deal with the local heap
of the process so they're "near" memory functions. Under Win32, these two types
are identical. Whether you call GlobalAlloc or LocalAlloc, you get the same result.
<br>
Steps in allocating and using memory are as follows:
<ol>
<li> Allocate a block of memory by calling <b>GlobalAlloc</b>. This function
returns a handle to the requested memory block.</li>
<li> "Lock" the memory block by calling <b>GlobalLock</b>. This function accepts
a handle to the memory block and returns a pointer to the memory block.</li>
<li> You can use the pointer to read or write memory.</li>
<li> "Unlock" the memory block by calling <b>GlobalUnlock</b> . This function
invalidates the pointer to the memory block.</li>
<li> Free the memory block by calling <b>GlobalFree</b>. This function accepts
the handle to the memory block.</li>
</ol>
You can also substitute "Global" by "Local" such as LocalAlloc, LocalLock,etc.
<br>
The above method can be further simplified by using a flag in GlobalAlloc call,
GMEM_FIXED. If you use this flag, the return value from Global/LocalAlloc will
be the pointer to the allocated memory block, not the memory block handle. You
don't have to call Global/LocalLock and you can pass the pointer to Global/LocalFree
without calling Global/LocalUnlock first. But in this tutorial, I'll use the "traditional"
approach since you may encounter it when reading the source code of other programs.
<p>File I/O under Win32 bears remarkable semblance to that under DOS. The steps
needed are the same. You only have to change interrupts to API calls and it's
done. The required steps are the followings: <br>
<ol>
<li> Open or Create the file by calling <b>CreateFile</b> function. This function
is very versatile: in addition to files, it can open communication ports,
pipes, disk drives or console. On success, it returns a handle to file or
device. You can then use this handle to perform operations on the file or
device.</li>
<br>
Move the file pointer to the desired location by calling <b>SetFilePointer</b>.
<li> Perform read or write operation by calling <b>ReadFile</b> or <b>WriteFile</b>.
These functions transfer data from a block of memory to or from the file.
So you have to allocate a block of memory large enough to hold the data.</li>
<li> Close the file by calling <b>CloseHandle</b>. This function accepts the
file handle.</li>
</ol>
<h3> Content:</h3>
The program listed below displays an open file dialog box. It lets the user select
a text file to open and shows the content of that file in an edit control in its
client area. The user can modify the text in the edit control as he wishes, and
can choose to save the content in a file.
<p><b>.386</b> <br>
<b>.model flat,stdcall</b> <br>
<b>option casemap:none</b> <br>
<b>WinMain proto :DWORD,:DWORD,:DWORD,:DWORD</b> <br>
<b>include \masm32\include\windows.inc</b> <br>
<b>include \masm32\include\user32.inc</b> <br>
<b>include \masm32\include\kernel32.inc</b> <br>
<b>include \masm32\include\comdlg32.inc</b> <br>
<b>includelib \masm32\lib\user32.lib</b> <br>
<b>includelib \masm32\lib\kernel32.lib</b> <br>
<b>includelib \masm32\lib\comdlg32.lib</b>
<p><b>.const</b> <br>
<b>IDM_OPEN equ 1</b> <br>
<b>IDM_SAVE equ 2</b> <br>
<b>IDM_EXIT equ 3</b> <br>
<b>MAXSIZE equ 260</b> <br>
<b>MEMSIZE equ 65535</b>
<p><b>EditID equ 1
; ID of the edit control</b>
<p><b>.data</b> <br>
<b>ClassName db "Win32ASMEditClass",0</b> <br>
<b>AppName db "Win32 ASM Edit",0</b> <br>
<b>EditClass db "edit",0</b> <br>
<b>MenuName db "FirstMenu",0</b> <br>
<b>ofn OPENFILENAME <></b> <br>
<b>FilterString db "All Files",0,"*.*",0</b> <br>
<b>
db "Text Files",0,"*.txt",0,0</b> <br>
<b>buffer db MAXSIZE dup(0)</b>
<p><b>.data?</b> <br>
<b>hInstance HINSTANCE ?</b> <br>
<b>CommandLine LPSTR ?</b> <br>
<b>hwndEdit HWND ?
; Handle to the edit control</b> <br>
<b>hFile HANDLE ?
; File handle</b> <br>
<b>hMemory HANDLE ?
;handle to the allocated memory block</b> <br>
<b>pMemory DWORD ?
;pointer to the allocated memory block</b> <br>
<b>SizeReadWrite DWORD ?
; number of bytes actually read or write</b>
<p><b>.code</b> <br>
<b>start:</b> <br>
<b> invoke GetModuleHandle, NULL</b> <br>
<b> mov hInstance,eax</b> <br>
<b> invoke GetCommandLine<br>
mov CommandLine,eax</b> <br>
<b> invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT</b>
<br>
<b> invoke ExitProcess,eax</b>
<p><b>WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:SDWORD</b>
<br>
<b> LOCAL wc:WNDCLASSEX</b> <br>
<b> LOCAL msg:MSG</b> <br>
<b> LOCAL hwnd:HWND</b> <br>
<b> mov wc.cbSize,SIZEOF WNDCLASSEX</b> <br>
<b> mov wc.style, CS_HREDRAW or CS_VREDRAW</b>
<br>
<b> mov wc.lpfnWndProc, OFFSET WndProc</b> <br>
<b> mov wc.cbClsExtra,NULL</b> <br>
<b> mov wc.cbWndExtra,NULL</b> <br>
<b> push hInst</b> <br>
<b> pop wc.hInstance</b> <br>
<b> mov wc.hbrBackground,COLOR_WINDOW+1</b> <br>
<b> mov wc.lpszMenuName,OFFSET MenuName</b> <br>
<b> mov wc.lpszClassName,OFFSET ClassName</b>
<br>
<b> invoke LoadIcon,NULL,IDI_APPLICATION</b> <br>
<b> mov wc.hIcon,eax</b> <br>
<b> mov wc.hIconSm,eax</b> <br>
<b> invoke LoadCursor,NULL,IDC_ARROW</b> <br>
<b> mov wc.hCursor,eax</b> <br>
<b> invoke RegisterClassEx, addr wc</b> <br>
<b> invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR
AppName,\</b> <br>
<b> WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\</b>
<br>
<b> CW_USEDEFAULT,300,200,NULL,NULL,\</b>
<br>
<b> hInst,NULL</b>
<br>
<b> mov hwnd,eax</b> <br>
<b> invoke ShowWindow, hwnd,SW_SHOWNORMAL</b> <br>
<b> invoke UpdateWindow, hwnd</b> <br>
<b> .WHILE TRUE</b> <br>
<b> invoke GetMessage, ADDR msg,NULL,0,0</b>
<br>
<b> .BREAK .IF (!eax)</b> <br>
<b> invoke TranslateMessage, ADDR
msg</b> <br>
<b> invoke DispatchMessage, ADDR msg</b>
<br>
<b> .ENDW</b> <br>
<b> mov eax,msg.wParam</b> <br>
<b> ret</b> <br>
<b>WinMain endp</b>
<p><b>WndProc proc uses ebx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM</b>
<br>
<b> .IF uMsg==WM_CREATE</b> <br>
<b> invoke CreateWindowEx,NULL,ADDR
EditClass,NULL,\</b> <br>
<b>
WS_VISIBLE or WS_CHILD or ES_LEFT or ES_MULTILINE or\</b> <br>
<b>
ES_AUTOHSCROLL or ES_AUTOVSCROLL,0,\</b> <br>
<b>
0,0,0,hWnd,EditID,\</b> <br>
<b>
hInstance,NULL</b> <br>
<b> mov hwndEdit,eax</b> <br>
<b> invoke SetFocus,hwndEdit</b> <br>
<b>;==============================================</b> <br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -