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

深入理解 MASM 巨集:從字串常數到編譯器展開

     編輯:組合語言

前言

許多組語開發者習慣使用副程式(PROC)而非巨集,擔心巨集會導致程式碼膨脹。然而,巨集在編譯期展開,能產生極精簡的機器碼,甚至優於手寫的資料段定義。本文透過實例剖析 MASM 巨集 CTEXT,展示其如何將字串常數自動置於 .const 區段,並產生與手寫版本完全相同的執行檔。

巨集定義與使用

CTEXT MACRO y:VARARG
    LOCAL sym
    CONST segment
    ifidni ,<>
        sym db 0
    else
        sym db y,0
    endif
    CONST ends
    exitm
ENDM

.code
Start:
    invoke MessageBoxA, NULL, CTEXT("Hello, world !"), CTEXT("Hi!"), MB_ICONINFORMATION
    invoke ExitProcess, NULL
end Start

編譯器預處理輸出(/EP 參數)

使用 ml /c /coff /I include /EP 20-1.asm > L.txt 可查看巨集展開後的中間碼:

.code
Start:
    CONST segment
    ??0019 db "Hello, world !",0
    CONST ends
    CONST segment
    ??001A db "Hi!",0
    CONST ends
    invoke MessageBoxA, NULL, offset ??0019, offset ??001A, MB_ICONINFORMATION
    invoke ExitProcess, NULL
end Start

巨集自動產生唯一標籤(??0019、??001A),並將字串置於 CONST 區段,最後以 offset 取得位址傳遞給 API。

與手寫版本比較

手寫版本(20-2.asm)在 .const 區段定義 xx、yy 並使用 addr 取址。對比兩個編譯後的 EXE(fc /b),僅差異於 TimeDateStamp(編譯時間戳),機器碼完全一致。

區段屬性對檔案大小的影響

若在 .code 區段直接定義字串(20-3.asm),字串會被置於 .data 區段,導致 PE 檔多出一個區段,檔案體積變大。巨集 CTEXT 確保字串進入唯讀區段(.rdata),不僅節省空間,也符合 Windows 記憶體管理最佳實務(共享唯讀頁)。

結論

  • 善用巨集可減少重複勞動,自動處理字串常數的區段配置與標籤命名。
  • 巨集展開後的程式碼與手寫最佳化版本無異,不會造成程式膨脹。
  • 理解編譯器預處理輸出(/EP)有助於除錯與學習巨集機制。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved