天天看點

《Windows環境下32位彙編語言程式設計(第2版)》-chapter10

第四章到第九章講了一些UI的操作,還有時間及繪圖,最近一直在研究寫一個文本編輯器就好久沒發文章了,編輯器也快寫完了,之後還準備寫個檔案搜尋器,練習資料庫和多線程。

第十章是檔案操作和記憶體管理,寫文本編輯器也就用到這暫時,現在把這一章的筆記貼出來。我發現儲存成rtf格式,在代碼片中,所有的縮進就都正常了。

10
	10.1.1
		--------标準記憶體管理函數-	|-------------------------
		----堆管理函數-----------|---記憶體映射檔案函數---
		虛拟記憶體管理函數---------	|-------------------------
		
		------------------Windows記憶體管理器-----------------
		---------------實體記憶體-------交換檔案-------------
		
		虛拟記憶體管理函數:保留送出釋放虛拟記憶體
		堆管理函數:操作所有的預設堆和裡面的私有堆
		标準記憶體管理函數:在預設堆内配置設定和釋放記憶體
		記憶體映射檔案函數:把檔案映射到記憶體後,在記憶體中讀寫檔案
	10.1.2
		一個程序4GB,高2GB給系統核心使用,低2GB自己用
		
		申請記憶體前,需要知道現在記憶體的配置設定情況
			invoke	GlobalMemoryStatus, lpBuffer
			lpBuffer: MEMORYSTATUS
			dwLength		dw	?	;本結構長度
			dwMemoryLod	dw	?	;已用記憶體百分比
			dwTotalPhys		dw	?	;實體記憶體總量
			dwAvailPhys		dw 	?	;可用實體記憶體
			...
			調用前先填寫dwLength,調用成功後,函數在結構中傳回對應的數值
	10.1.3		
		标準記憶體管理函數(預設堆中)
			GlobalAlloc
			GlobalFree
			GlobalReAlloc
			GlobalLock
			GlobalUnlock
			GlobalDiscard
			GlobalFlags
			GlobalHandle
			GlobalSize
			固定的記憶體塊
				//申請
				invoke	GlobalAlloc, GMEM_FIXED or GMEM_ZEROINT, dwSizeInByte
				//申請成功傳回記憶體指針,不成功傳回NULL
				.if		eax
						mov		lpMemory, eax
				.endif
				//釋放
				invoke	GlobalFree, lpMemory
				//釋放成功傳回NULL,不成功傳回lpMemory
				//手動釋放防止記憶體洩漏,程式結束後系統自動釋放
				//修改大小
				invoke	GlobalReAlloc, lpMemory, dwSizeInByte, GMEM_ZEROINT or GMEM_MOVABLE
				//申請成功傳回記憶體指針,不成功傳回NULL
				//原空間已有資料會複制到新空間
				.if		eax 
						mov	lpMemory, eax
				.endif
			可移動的記憶體塊(消除碎片化)
				//申請
				invoke 	GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINT, dwSizeInByte
				.if		eax 
						mov		hMemory, eax
				//使用之前先鎖定,Windows不會移動它
				invoke 	GlobalLock, hMemory
				.if		eax
						mov		lpMemory, eax
				.endif
				//暫時不用,可以解鎖
				invoke 	GlobalUnlock, hMemory
				//鎖定和解鎖配對使用才行
				//釋放(不論是否鎖定)
				invoek 	GlobalFree, hMemory
				//修改大小
				invoke 	GlobalReAlloc, hMemory, dwSizeInByte, GMEM_ZEROINT or GMEM_MOVEABLE
				//修改大小前先解鎖!
			可丢棄的記憶體塊
				//申請
				invoke 	GlobalAlloc, GHND or GMEM_DISCARDABLE
				.if 	eax
						mov		hMemory, eax
				.endif
				//記憶體塊被丢棄時資料丢失,無法鎖定,但是可以重新配置設定
				//記憶體塊處于非鎖定狀态,可以手動丢棄
				invoke	GlobalDiscard, hMemory
				//鎖定和解鎖和釋放和修改大小同可移動的記憶體塊
			擷取記憶體塊資訊
				//擷取鎖定計數,是否被丢棄
				invoke	GlobalFlags, hMemory
				//GMEM_INVALID_HANDLE:調用失敗
				//低8位代表鎖定計數
				//擷取記憶體塊句柄
				invoke 	GlobalHandle, lpMemory
				//擷取記憶體塊大小
				invoke 	GlobalSize, hMemory
	10.1.4
		堆管理函數
			在預設堆(同步)中的私有堆配置設定記憶體(可建立多個),實作多線程,提高效率
			利于實作子產品的記憶體封裝,提高穩定性
			
			//建立私有堆
			invoke 	HeapCreate, uFlags, dwInitSize, dwMaxSize
			.if		eax && (eax < 0c00000000h)
					mov 	hHeap, eax
			.endif
			//釋放私有堆
			invoke 	HeapDestroy, hHeap
			//在私有堆中配置設定記憶體(隻能配置設定固定的記憶體塊)
			invoke	HeapAlloc, hHeap, HEAP_ZERO_MEMORY, dwSizeInByte
			.if		eax && (eax < 0c0000000h)
					mov 	lpMemory, eax
			.endif
			//有關獨占性和是否傳回錯誤碼的問題
			//釋放記憶體
			invoke	HeapFree, hHeap, dwFlags, lpMemory
			//重新調整大小
			invoke 	HeapReAlloc, hHeap, dwFlags, lpMemory, dwSizeInByte
			.if 	eax && (eax < 0c0000000h)
					mov		lpMemory,eax
			.endif
	10.1.5
		虛拟記憶體管理函數
		程序中的每個位址:
			送出狀态(占用狀态):線程位址已經映射到實際的實體記憶體中
			自由狀态:沒有映射,程式會用,還沒被使用
			保留狀态:沒有映射,程式不會用,将來可能會用
			
		保留和釋放位址空間
			invoke	VirtualAlloc, lpAddress, dwSize, flAllocationType, flProtect
			invoke 	VirtualFree, lpAddress, 0, MEM_RELEASE
		記憶體頁的保護和鎖定
			invoke	VirtualProtect, lpAddress, dwSize, flNewProtect, lpflOldProtect
			invoke 	VirtualLock, lpAddress, dwSize
			invoke  VirtualUnlock, lpAddress, dwSize
	10.1.6
		其他記憶體管理函數
		移動記憶體
			invoke	RtlMoveMemory, offset szDest, offset szSource, dwSize
		填充記憶體塊
			invoke 	RtlFileMemory, offset szDest, dwSize, dbFill
		用0填充
			invoke 	RtlZeroMemory, offset szDest, dwSize
		記憶體狀态檢測
			invoke 	IsBadCodePtr, lpMemory			;指針指向的單位元組是否可讀
			invoke 	IsBadReadPtr, lpMemory, dwSize  	;某段記憶體是否可讀
			invoke 	IsBadWritePre, lpMemory, dwSize		;某段記憶體是否可寫
			invoke	IsBadStringPre, lpMemory, dwSize	;字元串是否可讀
           
10
	10.2.1
		檔案句柄和讀寫指針
	10.2.2
		打開/建立檔案
			HANDLE CreateFile(//傳回一個檔案句柄
				LPCTSTR lpFileName,//全路徑檔案名
				DWORD dwDesiredAccess,//GENERIC_READ or GENERIC_WRITE
				DWORD dwShareMode,//FILE_SHARE_READ or FILE_SHARE_WRITE
				LPSECURITY_ATTRIBUTES lpSecurityAttributes,//NULL
				DWORD dwCreationDisposition,//CREATE_NEW/CREATE_ALWAYS/OPEN_EXISTING/OPEN_ALWAYS
				DWORD dwFlagsAndAttributes,//FILE_ATTRIBUTE_NORMAL
				HANDLE hTemplateFile//NULL
				);
		關閉檔案
			BOOL CloseHandle(HANDLE hObject);
		移動檔案指針
			DWORD SetFilePointer(
				HANDLE hFile,//檔案句柄
				LONG lDistanceToMove,//移動距離低32位,有符号
				PLONG lpDistanceToMoveHigh,//移動距離高32位,一般NULL
				DWORD dwMoveMethod//FILE_BEGIN/FILE_CURRENT/FIEL_END(移動距離為負)
				);
		擷取目前檔案指針
			invoke	SetFilePointer, hFile, 0, NULL, FILE_CURRENT
		設定檔案結尾
			invoke	SetEndOfFile, hFile//把目前指針設定為檔案結尾
			//若目前指針超出原檔案傳回,不報錯,檔案變長, 可以用來建立空檔案
		讀/寫檔案
			invoke	ReadFile, hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped(異步讀寫用,一般NULl)
			invoke	WriteFile, hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped(異步讀寫用,一般NULl)
		清空資料緩沖區并寫入
			invoke	FlushFileBuffers, hFile
		加鎖/解鎖檔案防其他程序對該區域讀寫
			invoke	LockFile, hFile, dwFileOffsetLow, dwFileOffsetHign, nNumberOfBytesToLockLow, nNumberOfBytesToLockHign
			invoke	UnlockFile, hFile, dwFileOffsetLow, dwFileOffsetHign, nNumberOfBytesToLockLow, nNumberOfBytesToLockHign
	10.2.3
		查找檔案(編寫防毒軟體等)
			涉及到多線程,略,準備單獨寫一個檔案搜尋器
		
	10.2.4
		檔案屬性
		擷取檔案類型
			invoke	GetFileType, hFile
			return FILE_TYPE_UNKNOWN, FILE_TYPE_DISK, FILE_TYPE_CHAR, FILE_TYPE_PIPE
					未知			磁盤檔案		字元裝置		管道
		擷取檔案長度
			invoke 	GetFileSize, hFile, lpFileSizeHigh//NULL
			return 長度的低32位
		擷取檔案日期
			invoke 	GetFileTime, hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime//FILETIME
			invoke  FileTimeToSystemTime, lpFileTime, lpSystemTime//SYSTEMTIME
		設定檔案日期
			invoke 	SystemTimeToFileTime, lpSystemTime, lpFileTime
			invoke 	SetFileTime, hFile, lpCreationTime, lpLastAccessTime, lpLastAccessTime
		擷取檔案屬性
			invoke 	GetFileAttrubutes, lpFileAllPathName
		設定檔案屬性
			invoke	SetFileAttrubutes, lpFileAllPathName, dwFileAttributes//與CreateFile中的參數同
	10.2.5
		拷貝檔案
			invoke	CopyFile, lpExistingFileName, lpNewFileName, bFailIfExists//檔案存在是,FALSE覆寫,TRUE失敗
			CopyFileEx//提供回調函數,如顯示進度條,拷貝大型檔案有用
		移動檔案
			invoke 	MoveFile, lpExistingFileName, lpNewFileName//目标檔案名必須不存在
			MoveFileEx//提供一個dwFlags參數,略
		删除檔案
			invoke	DeleteFile, lpFileName//檔案必須關閉
			
           
10
	10.3
		每個邏輯驅動器的标号叫“卷标”
		每個邏輯驅動器中的檔案按樹型存儲
	10.3.1
		卷标操作
		修改卷标
		szPath		db	'c:\', 0		;\反斜杠不能省略
		szVolume	db	'NewName', 0
		invoke 		SetVolumeLabel, addr szPath, addr szVolume
		删除卷标
		invoke		SetVolumeLabel, addr szPath, NULL
		擷取卷标
		invoke 		GetLogicalDrives
		invoke 		GetLogicalDriveStrings, dwBufferSize, lpBuffer
		擷取邏輯驅動器或光驅參數
		invoke 		GetDriveType, addr szPath
		GetVolumInformation可以擷取更多資訊
	10.3.2
		目錄操作
		建立和删除目錄
		szDir		db	'c:\dir\2', 0	;上級目錄必須存在且子目錄不存在
		invoke 		CreateDirectory, addr szDir, NULL
		invoke		RemoveDirectory, addr szDir      ;目錄必須為空才能删除
		擷取特殊目錄
		invoke 		GetCurrentDirectory, dwBufferSize, lpBuffer	;擷取目前目錄
		invoke		GetTempPath, dwBufferSize, lpBuffer			;擷取臨時目錄
		invoke 		GetWindwosDirectory, lpBuffer, dwBufferSize	;擷取Windows目錄,System32
		invoke 		GetSystemDirectory, lpBuffer, dwBufferSize	;擷取系統目錄
		invoke 		SetCurrentDirectory, addr szDir
	10.4
		記憶體映射檔案(解決緩沖區邊界判斷問題,記憶體洩漏)
		CreateFileMapping, OpenFileMapping, MapViewOfFile, UnmapViewOfFile, FlushViewOfFile
           

繼續閱讀