⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lion-tutorial13.htm

📁 内有一些代码
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<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 13: Memory Mapped Files</p>
<hr size="1">
I'll show you what memory mapped files are and how to use them to your advantages. 
Using a memory mapped file is quite easy as you'll see in this tutorial. 
<p>Download the example <a href="files/tut13.zip">here</a>. 
<h3> Theory:</h3>
If you examine the example in the previous tutorial closely, you'll find that 
it has a serious shortcoming: what if the file you want to read is larger than 
the allocated memory block? or what if the string you want to search for is cut 
off in half at the end of the memory block? The traditional answer for the first 
question is that you should repeatedly read in the data from the file until the 
end of file is encountered. The answer to the second question is that you should 
prepare for the special case at the end of the memory block. This is called a 
boundary value problem. It presents headaches to programmers and causes innumerable 
bugs. <br>
It would be nice if we can allocate a very large block of memory, enough to store 
the whole file but our program would be a resource hog. File mapping to the rescue. 
By using file mapping, you can think of the whole file as being already loaded 
into memory and you can use a memory pointer to read or write data from the file. 
As easy as that. No need to use memory API functions and separate File I/O API 
functions anymore, they are one and the same under file mapping. File mapping 
is also used as a means to share data between processes. Using file mapping in 
this way, there's no actual file involved. It's more like a reserved memory block 
that every process can *see*. But sharing data between processes is a delicate 
subject, not to be treated lightly. You have to implement process and thread synchronization 
else your applications will crash in very short order. <br>
We will not touch the subject of file mapping as a means to create a shared memory 
region in this tutorial. We'll concentrate on how to use file mapping as a means 
to "map" a file into memory. In fact, the PE loader uses file mapping to load 
executable files into memory. It is very convenient since only the necessary portions 
can be selectively read from the file on the disk. Under Win32, you should use 
file mapping as much as possible. <br>
There are some limitation to file mapping though. Once you create a memory mapped 
file, its size cannot be changed during that session. So file mapping is great 
for read-only files or file operations that don't affect the file size. That doesn't 
mean that you cannot use file mapping if you want to increase the file size. You 
can estimate the new size and create the memory mapped file based on the new size 
and the file will grow to that size. It's just inconvenient, that's all. <br>
Enough for the explanation. Let's dive into implementation of file mapping. In 
order to use file mapping, these steps must be performed: 
<ol>
  <li> call <b>CreateFile</b> to open the file you want to map.</li>
  <li> call <b>CreateFileMapping</b> with the file handle returned by CreateFile 
    as one of its parameter. This function creates a file mapping object from 
    the file opened by CreateFile.</li>
  <li> call <b>MapViewOfFile</b> to map a selected file region or the whole file 
    to memory. This function returns a pointer to the first byte of the mapped 
    file region.</li>
  <li> Use the pointer to read or write the file</li>
  <li> call <b>UnmapViewOfFile</b> to unmap the file.</li>
  <li> call <b>CloseHandle</b> with the handle to the mapped file as the parameter 
    to close the mapped file.</li>
  <li> call <b>CloseHandle</b> again this time with the file handle returned by 
    CreateFile to close the actual file.</li>
</ol>
<h3> Example:</h3>
The program listed below lets you open a file via an open file dialog box. It 
opens the file using file mapping, if it's successful, the window caption is changed 
to the name of the opened file. You can save the file in another name by select 
File/Save as menuitem. The program will copy the whole content of the opened file 
to the new file. Note that you don't have to call GlobalAlloc to allocate a memory 
block in this program. 
<p><b>.386</b> <br>
  <b>.model flat,stdcall</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> 
<p><b>.data</b> <br>
  <b>ClassName db "Win32ASMFileMappingClass",0</b> <br>
  <b>AppName&nbsp; db "Win32 ASM File Mapping Example",0</b> <br>
  <b>MenuName db "FirstMenu",0</b> <br>
  <b>ofn&nbsp;&nbsp; OPENFILENAME &lt;></b> <br>
  <b>FilterString db "All Files",0,"*.*",0</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  db "Text Files",0,"*.txt",0,0</b> <br>
  <b>buffer db MAXSIZE dup(0)</b> <br>
  <b>hMapFile HANDLE 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; Handle to the memory mapped file, must be</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ;initialized with 0 because we also use it as</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ;a flag in WM_DESTROY section too</b> 
<p><b>.data?</b> <br>
  <b>hInstance HINSTANCE ?</b> <br>
  <b>CommandLine LPSTR ?</b> <br>
  <b>hFileRead HANDLE ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; Handle to the source file</b> <br>
  <b>hFileWrite HANDLE ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; Handle to the output file</b> <br>
  <b>hMenu HANDLE ?</b> <br>
  <b>pMemory DWORD ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; pointer to the data in the source file</b> <br>
  <b>SizeWritten DWORD ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ; number of bytes actually written by WriteFile</b> 
<p><b>.code</b> <br>
  <b>start:</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke GetModuleHandle, NULL</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp; hInstance,eax</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke GetCommandLine</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov CommandLine,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke WinMain, hInstance,NULL,CommandLine, 
  SW_SHOWDEFAULT</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke ExitProcess,eax</b> 
<p><b>WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL wc:WNDCLASSEX</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL msg:MSG</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL hwnd:HWND</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbSize,SIZEOF WNDCLASSEX</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.style, CS_HREDRAW or CS_VREDRAW</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.lpfnWndProc, OFFSET WndProc</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbClsExtra,NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbWndExtra,NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; push&nbsp; hInst</b> <br>
  <b>&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; wc.hInstance</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hbrBackground,COLOR_WINDOW+1</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.lpszMenuName,OFFSET MenuName</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.lpszClassName,OFFSET ClassName</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; invoke LoadIcon,NULL,IDI_APPLICATION</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hIcon,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hIconSm,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke LoadCursor,NULL,IDC_ARROW</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hCursor,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke RegisterClassEx, addr wc</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,\</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ADDR AppName, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\</b> <br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -