首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

Win32 組合語言教程:記憶體管理與檔案 I/O 完整實作

     編輯:組合語言

前言

Win32 平坦記憶體模型賦予每程式 4GB 獨立位址空間,消除 near/far 指標困擾。本文系統說明全域/區域記憶體 API、GMEM_FIXED 簡化用法、檔案 I/O 基礎流程,並以編輯器範例展開:通用對話框開啟/儲存檔案、編輯控件顯示/編輯、記憶體區塊讀寫協調。

Win32 記憶體管理 API

傳統流程(可移動記憶體)

  1. GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, size) → 返回控制碼
  2. GlobalLock(hMem) → 返回指標,鎖定記憶體防止移動
  3. 透過指標讀寫資料
  4. GlobalUnlock(hMem) → 解鎖,指標失效
  5. GlobalFree(hMem) → 釋放

LocalAlloc/Lock/Unlock/Free 行為相同(Win32 統一實作)。

簡化流程:GMEM_FIXED

GlobalAlloc(GMEM_FIXED, size) 直接返回指標,無需 Lock/Unlock,釋放時直接 GlobalFree(ptr)。但傳統模式相容性較佳,範例採傳統寫法。

檔案 I/O 基礎 API

  1. CreateFile:開啟/建立檔案、裝置、管道等,返回檔案控制碼
  2. SetFilePointer:移動檔案指標
  3. ReadFile / WriteFile:實際資料傳輸,自動處理記憶體緩衝
  4. CloseHandle:關閉控制碼

CreateFile 關鍵參數

參數常用值說明
dwDesiredAccessGENERIC_READ / GENERIC_WRITE / 兩者 OR存取權限
dwShareModeFILE_SHARE_READ / FILE_SHARE_WRITE / 0共享模式,0=獨佔
dwCreationDispositionCREATE_NEW / CREATE_ALWAYS / OPEN_EXISTING / OPEN_ALWAYS / TRUNCATE_EXISTING檔案存在/不存在時行為
dwFlagsAndAttributesFILE_ATTRIBUTE_ARCHIVE / NORMAL / HIDDEN / READONLY / SYSTEM / COMPRESSED檔案屬性

範例程式:簡易文字編輯器

主視窗客戶區填滿編輯控件(ES_MULTILINE|ES_AUTOVSCROLL|ES_AUTOHSCROLL),選單提供 Open/Save,使用 GetOpenFileName/GetSaveFileName 通用對話框。

WM_CREATE:建立編輯控件與初始化 OPENFILENAME

.IF uMsg==WM_CREATE
  invoke CreateWindowEx, NULL, ADDR EditClass, NULL,
      WS_VISIBLE|WS_CHILD|ES_LEFT|ES_MULTILINE|ES_AUTOHSCROLL|ES_AUTOVSCROLL,
      0,0,0,0, hWnd, EditID, hInstance, NULL
  mov hwndEdit, eax
  invoke SetFocus, hwndEdit

  ; OPENFILENAME 共用欄位初始化
  mov ofn.lStructSize, SIZEOF ofn
  push hWnd; pop ofn.hwndOwner
  push hInstance; pop ofn.hInstance
  mov ofn.lpstrFilter, OFFSET FilterString
  mov ofn.lpstrFile, OFFSET buffer
  mov ofn.nMaxFile, MAXSIZE

WM_SIZE:編輯控件隨視窗縮放

.ELSEIF uMsg==WM_SIZE
  mov eax, lParam
  mov edx, eax
  shr edx, 16          ; 高字 = 高度
  and eax, 0FFFFh      ; 低字 = 寬度
  invoke MoveWindow, hwndEdit, 0, 0, eax, edx, TRUE

IDM_OPEN:開啟檔案完整流程

.if ax==IDM_OPEN
  mov ofn.Flags, OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_LONGNAMES|OFN_EXPLORER|OFN_HIDEREADONLY
  invoke GetOpenFileName, ADDR ofn
  .if eax==TRUE
    invoke CreateFile, ADDR buffer, GENERIC_READ|GENERIC_WRITE,
        FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
    mov hFile, eax
    invoke GlobalAlloc, GMEM_MOVEABLE|GMEM_ZEROINIT, MEMSIZE
    mov hMemory, eax
    invoke GlobalLock, hMemory
    mov pMemory, eax
    invoke ReadFile, hFile, pMemory, MEMSIZE-1, ADDR SizeReadWrite, NULL
    invoke SendMessage, hwndEdit, WM_SETTEXT, NULL, pMemory
    invoke CloseHandle, hFile
    invoke GlobalUnlock, pMemory
    invoke GlobalFree, hMemory
  .endif
  invoke SetFocus, hwndEdit

IDM_SAVE:儲存檔案完整流程

.elseif ax==IDM_SAVE
  mov ofn.Flags, OFN_LONGNAMES|OFN_EXPLORER|OFN_HIDEREADONLY
  invoke GetSaveFileName, ADDR ofn
  .if eax==TRUE
    invoke CreateFile, ADDR buffer, GENERIC_READ|GENERIC_WRITE,
        FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_ARCHIVE, NULL
    mov hFile, eax
    invoke GlobalAlloc, GMEM_MOVEABLE|GMEM_ZEROINIT, MEMSIZE
    mov hMemory, eax
    invoke GlobalLock, hMemory
    mov pMemory, eax
    invoke SendMessage, hwndEdit, WM_GETTEXT, MEMSIZE-1, pMemory
    invoke WriteFile, hFile, pMemory, eax, ADDR SizeReadWrite, NULL
    invoke CloseHandle, hFile
    invoke GlobalUnlock, pMemory
    invoke GlobalFree, hMemory
  .endif
  invoke SetFocus, hwndEdit

關鍵技巧總結

  1. 編輯控件尺寸 0,0,0,0:WM_CREATE 先建立,WM_SIZE 再用 MoveWindow 精確鋪滿客戶區。
  2. OPENFILENAME 重用:WM_CREATE 初始化共用欄位,命令處理只更新 Flags 與呼叫對話框。
  3. 記憶體區塊大小:範例固定 64KB(MEMSIZE=65535),大檔案需分段讀寫或改用記憶體對應檔案(下一課主題)。
  4. 焦點管理:對話框關閉後必須 SetFocus 回編輯控件,否則鍵盤輸入失效。
  5. 錯誤處理:範例簡化省略 API 返回值檢查,實務必須完整驗證。

總結

Win32 記憶體管理與檔案 I/O API 設計一致、邏輯清晰。掌握 GlobalAlloc/Lock/Unlock/Free 生命週期、CreateFile 豐富參數組合、通用對話框整合、編輯控件訊息操作(WM_SETTEXT/WM_GETTEXT),即可構建功能完整的檔案處理應用程式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved