
簡(jiǎn)介這份資源面向在Windows 10環(huán)境下學(xué)習(xí)匯編語(yǔ)言、需要搭建底層開(kāi)發(fā)工具鏈的初學(xué)者與系統(tǒng)編程愛(ài)好者核心提供MASM.exe匯編器與Link.exe鏈接器解決Win10下缺少可用匯編編譯與鏈接工具、無(wú)法將.asm源碼轉(zhuǎn)為可執(zhí)行文件的問(wèn)題。壓縮包共11個(gè)文件以9個(gè)exe可執(zhí)行程序?yàn)橹髁砗?個(gè)html說(shuō)明頁(yè)與1個(gè)doc文檔整體約173KB體積輕便便于快速部署到本地命令行環(huán)境。其中MASM負(fù)責(zé)將匯編指令翻譯為機(jī)器碼Link負(fù)責(zé)合并目標(biāo)文件、解析外部引用并生成EXE或DLL配套文檔可輔助理解工具用途與調(diào)用方式。已有1048人學(xué)習(xí)下載適合想深入理解計(jì)算機(jī)底層機(jī)制、練習(xí)匯編指令與鏈接流程的讀者可作為搭建Win10匯編實(shí)驗(yàn)環(huán)境的實(shí)用工具集。1. 在 Win10 上跑通 MASM.exe 和 Link.exe為什么 64 位系統(tǒng)反而要裝 32 位工具鏈很多人第一次在 Win10 上寫(xiě)匯編卡住的地方不是指令集而是找不到 MASM.exe 和 Link.exe。網(wǎng)上搜到的教程要么讓你去裝整個(gè) Visual Studio要么給一個(gè)來(lái)路不明的壓縮包解壓完發(fā)現(xiàn) Link.exe 報(bào)「不是有效的 Win32 應(yīng)用程序」。我當(dāng)年也翻過(guò)這個(gè)車明明系統(tǒng)是 64 位為什么反而要跑 16 位或 32 位的鏈接器原因在于 MASM 這套工具鏈的歷史包袱。MASM.exe 是 16 位程序Link.exe 早期版本也是 16 位它們?cè)痉?wù)于 DOS 和早期 Windows 的實(shí)模式匯編。Win10 的 64 位版本已經(jīng)徹底移除了 NTVDMNT 虛擬 DOS 機(jī)所以你直接雙擊 16 位的 MASM.exe系統(tǒng)會(huì)彈一個(gè)「此應(yīng)用無(wú)法在你的電腦上運(yùn)行」。解決辦法不是換系統(tǒng)而是用 32 位的 MASM 和 Link它們能在 Win10 的 WOW64 子系統(tǒng)里正常跑。這篇筆記就圍繞「Win10 運(yùn)行匯編所需的編譯程序 MASM.exe 和連接程序 Link.exe」這件事把工具從哪來(lái)、怎么放、怎么配、怎么跑通第一個(gè)程序以及中間會(huì)踩的坑一次講清楚。適合正在學(xué) 8086 匯編、王爽《匯編語(yǔ)言》實(shí)驗(yàn)環(huán)境搭建、或者需要手寫(xiě)匯編做底層驗(yàn)證的從業(yè)者。2. 工具從哪來(lái)MASM.exe 和 Link.exe 的三種獲取路徑與選型2.1 為什么 MASM32 包是 Win10 下最省事的選擇MASM.exe 和 Link.exe 本身是微軟的工具但它們分散在不同年代的 SDK 和開(kāi)發(fā)包里。如果你只是要寫(xiě) 16 位實(shí)模式匯編比如課程實(shí)驗(yàn)里的 8086 程序最直接的路徑是 MASM32 這個(gè)第三方整合包。它把 MASM.exe、Link.exe、ML.exe、資源編譯器以及必要的庫(kù)文件打包在一起安裝后自帶一個(gè)簡(jiǎn)單的 IDE 和命令行環(huán)境。選它的理由很實(shí)際第一版本匹配。MASM32 里的 MASM.exe 通常是 6.14 或 6.15Link.exe 是 5.60 左右這兩個(gè)版本對(duì) 16 位匯編的兼容性最好不會(huì)出現(xiàn)新版本 Link 不認(rèn) OMF 格式目標(biāo)文件的問(wèn)題。第二路徑干凈。默認(rèn)裝在 C:\masm32bin 目錄下就是可執(zhí)行文件include 和 lib 目錄結(jié)構(gòu)清晰不用自己去拼。第三Win10 兼容。32 位程序在 WOW64 下運(yùn)行穩(wěn)定不需要額外開(kāi)兼容模式。常見(jiàn)做法是去 MASM32 的官網(wǎng)下載安裝包但如果你網(wǎng)絡(luò)環(huán)境不方便也可以從已有的 Visual Studio 安裝目錄里提取。VS 的 VC\bin 目錄下有 ml.exe 和 link.exe但那是 32 位保護(hù)模式的工具用來(lái)編譯 16 位 DOS 程序會(huì)報(bào)錯(cuò)。所以如果你明確要寫(xiě) 16 位匯編還是老老實(shí)實(shí)用 MASM32 包里的版本。2.2 從 Visual Studio 提取 Link.exe 的注意事項(xiàng)有些場(chǎng)景你不需要 16 位而是要在 Win10 上寫(xiě) 32 位保護(hù)模式匯編或者用匯編和 C 混合編程。這時(shí)候可以用 Visual Studio 自帶的 ml.exe 和 link.exe。它們位于 VS 安裝目錄的 VC\Tools\MSVC版本號(hào)\bin\Hostx64\x86 或 Hostx64\x64 下。這里有個(gè)關(guān)鍵點(diǎn)Hostx64\x86 目錄下的 link.exe 是 32 位鏈接器能生成 32 位 PE 文件Hostx64\x64 下的是 64 位鏈接器生成 64 位 PE。如果你用 32 位鏈接器去鏈 64 位目標(biāo)文件會(huì)報(bào)「模塊計(jì)算機(jī)類型 x64 與目標(biāo)計(jì)算機(jī)類型 x86 沖突」。反過(guò)來(lái)也一樣。所以提取之前先想清楚你要生成哪種位數(shù)的程序。另外VS 的 link.exe 依賴 mspdbcore.dll 等一堆動(dòng)態(tài)庫(kù)單獨(dú)把 link.exe 拷出來(lái)放到別的目錄會(huì)跑不起來(lái)。要么把整個(gè) bin 目錄加進(jìn) PATH要么用 VS 自帶的開(kāi)發(fā)者命令提示符。我一般會(huì)直接在 VS 的「x86 Native Tools Command Prompt」里操作省去配環(huán)境的麻煩。2.3 手動(dòng)整理一套最小工具集的目錄結(jié)構(gòu)如果你不想裝 MASM32 也不想裝完整 VS可以手動(dòng)整理一套最小工具集。需要的文件不多MASM.exe或 ml.exe、Link.exe、以及它們依賴的 DLL。16 位 MASM 通常只依賴 kernel32.dll 和 user32.dllWin10 自帶。Link.exe 5.60 也類似。我習(xí)慣的目錄結(jié)構(gòu)是這樣C:\asm\ ├── bin\ │ ├── MASM.exe │ ├── LINK.exe │ └── ML.exe ├── include\ │ └── (空16 位匯編一般不需要) ├── lib\ │ └── (空) └── work\ └── hello.asm把 C:\asm\bin 加進(jìn)系統(tǒng) PATH然后在 work 目錄里寫(xiě)源文件、編譯、鏈接。這樣目錄干凈換機(jī)器時(shí)整個(gè) C:\asm 拷走就能用。注意不要放在中文路徑或帶空格的路徑下Link.exe 對(duì)路徑里的空格處理很糟糕會(huì)報(bào)「cannot open file」但不說(shuō)具體是哪個(gè)文件。3. 在 Win10 上配置 MASM 和 Link 的命令行環(huán)境3.1 把 bin 目錄寫(xiě)進(jìn) PATH 的兩種方式第一種是臨時(shí)方式只在當(dāng)前命令行窗口生效。打開(kāi) cmd 或 PowerShell執(zhí)行set PATHC:\asm\bin;%PATH%這條命令把 C:\asm\bin 插到 PATH 最前面后面的 %PATH% 保留原有路徑。注意等號(hào)兩邊不要有空格否則會(huì)變成設(shè)置一個(gè)帶空格的變量名。執(zhí)行完可以用where masm驗(yàn)證如果輸出 C:\asm\bin\MASM.exe 就說(shuō)明生效了。第二種是永久方式通過(guò)系統(tǒng)屬性里的「環(huán)境變量」編輯 PATH把 C:\asm\bin 加進(jìn)去。Win10 的 PATH 編輯界面比 Win7 友好可以逐條添加。加完后要重新打開(kāi)命令行窗口才生效已經(jīng)開(kāi)著的窗口讀的是舊環(huán)境。我一般先用臨時(shí)方式測(cè)試確認(rèn)工具能跑通再寫(xiě)進(jìn)永久 PATH。這樣萬(wàn)一路徑寫(xiě)錯(cuò)不會(huì)影響其他程序。3.2 驗(yàn)證 MASM.exe 和 Link.exe 能否在 Win10 下正常響應(yīng)配好 PATH 后先別急著編譯程序單獨(dú)跑一下這兩個(gè)命令masm link如果直接回車后出現(xiàn)用法提示或版本信息說(shuō)明可執(zhí)行文件能被系統(tǒng)加載。如果報(bào)「不是內(nèi)部或外部命令」說(shuō)明 PATH 沒(méi)配好。如果報(bào)「此應(yīng)用無(wú)法在你的電腦上運(yùn)行」說(shuō)明你拿到的是 16 位版本需要換 32 位版本。MASM.exe 正常響應(yīng)時(shí)通常會(huì)輸出類似「Microsoft (R) Macro Assembler Version 6.14.8444」的版權(quán)信息然后等待輸入。Link.exe 會(huì)輸出「Microsoft (R) Segmented Executable Linker Version 5.60.339」之類??吹竭@些就說(shuō)明工具鏈在 Win10 下是活的。提示如果 masm 命令能跑但 link 報(bào)錯(cuò)先檢查 Link.exe 是不是從 64 位 VS 目錄里拷出來(lái)的。64 位 Link 不能鏈 16 位 OMF 文件。3.3 用 ML.exe 替代 MASM.exe 的兼容性說(shuō)明ML.exe 是 MASM 的后續(xù)版本支持更多偽指令和更現(xiàn)代的語(yǔ)法。在 Win10 下ML.exe 的 32 位版本同樣能通過(guò) WOW64 運(yùn)行。如果你寫(xiě)的匯編代碼用到了 .386、.model flat 這些保護(hù)模式偽指令用 ML.exe 比 MASM.exe 更合適。但要注意ML.exe 默認(rèn)生成的是 COFF 格式目標(biāo)文件而老版 Link.exe 5.60 只認(rèn) OMF 格式。如果你用 ML.exe 編譯再用老 Link 鏈接會(huì)報(bào)「invalid object file」。解決辦法是給 ML.exe 加 /omf 參數(shù)強(qiáng)制生成 OMF 格式ml /omf /c hello.asm link hello.obj;這樣 ML.exe 就等價(jià)于 MASM.exe 的作用。我一般在課程實(shí)驗(yàn)里用 MASM.exe在需要更現(xiàn)代語(yǔ)法時(shí)用 ML.exe 加 /omf。4. 從 hello.asm 到 hello.exe一次完整的編譯鏈接實(shí)操4.1 寫(xiě)一個(gè)最小可運(yùn)行的 16 位匯編源文件在 C:\asm\work 下新建 hello.asm內(nèi)容如下; hello.asm - 最小的 16 位 DOS 匯編程序 ; 編譯: masm hello.asm; ; 鏈接: link hello.obj; .model small ; 使用小內(nèi)存模型 .stack 100h ; 定義 256 字節(jié)棧空間 .data msg db Hello, MASM on Win10!, 0Dh, 0Ah, $ .code start: mov ax, data ; 取數(shù)據(jù)段地址 mov ds, ax ; 送入 DS mov ah, 09h ; DOS 功能號(hào) 09h: 顯示字符串 lea dx, msg ; DX 指向字符串首地址 int 21h ; 調(diào)用 DOS 中斷 mov ax, 4C00h ; DOS 功能號(hào) 4Ch: 帶返回碼退出 int 21h ; 返回碼 00h end start這段代碼做了三件事初始化數(shù)據(jù)段、用 INT 21h 的 09h 功能打印字符串、用 4Ch 功能退出。data是 MASM 的預(yù)定義符號(hào)會(huì)被替換成數(shù)據(jù)段的段地址。end start告訴匯編器程序入口是 start 標(biāo)號(hào)。4.2 用 MASM.exe 編譯成 OBJ 文件在 work 目錄下執(zhí)行masm hello.asm;分號(hào)表示后面沒(méi)有其他參數(shù)用默認(rèn)值。執(zhí)行后如果沒(méi)有任何錯(cuò)誤會(huì)生成 hello.obj。屏幕上會(huì)顯示類似Microsoft (R) Macro Assembler Version 6.14.8444 Copyright (C) Microsoft Corp 1981-1997. All rights reserved. Assembling: hello.asm 0 Warning Errors 0 Severe Errors如果報(bào)錯(cuò)常見(jiàn)的有兩種一是A2006: undefined symbol說(shuō)明用了一個(gè)沒(méi)定義的標(biāo)號(hào)或變量檢查拼寫(xiě)二是A2008: syntax error通常是偽指令寫(xiě)錯(cuò)比如.model寫(xiě)成了model。錯(cuò)誤信息里會(huì)帶行號(hào)對(duì)著改就行。4.3 用 Link.exe 鏈接成 EXE 文件編譯通過(guò)后執(zhí)行l(wèi)ink hello.obj;分號(hào)同樣表示用默認(rèn)參數(shù)。成功后會(huì)生成 hello.exe。輸出類似Microsoft (R) Segmented Executable Linker Version 5.60.339 Copyright (C) Microsoft Corp 1984-1993. All rights reserved. Run File [hello.exe]: List File [nul.map]: Libraries [.lib]: Definitions File [nul.def]:這里 Link 會(huì)交互式地問(wèn)幾個(gè)文件名直接回車用默認(rèn)值即可。分號(hào)的作用就是跳過(guò)這些提問(wèn)。如果報(bào)L2029: unresolved external說(shuō)明用到了外部符號(hào)但沒(méi)提供庫(kù)文件16 位 DOS 程序一般不會(huì)遇到除非你調(diào)用了 C 庫(kù)函數(shù)。4.4 在 Win10 上運(yùn)行生成的 EXE雙擊 hello.exe 大概率會(huì)閃退因?yàn)樗?16 位 DOS 程序Win10 64 位沒(méi)有 NTVDM。你需要用 DOSBox 來(lái)跑# 假設(shè) DOSBox 裝在 C:\DOSBox mount c C:\asm\work c: hello.exe在 DOSBox 里掛載 work 目錄為 C 盤(pán)然后運(yùn)行 hello.exe就能看到「Hello, MASM on Win10!」。如果你不想裝 DOSBox也可以用 32 位保護(hù)模式寫(xiě)程序那樣生成的 EXE 能直接在 Win10 下跑但那就不是 16 位實(shí)模式匯編了。注意Win10 的 32 位版本自帶 NTVDM可以直接跑 16 位程序。但 64 位版本沒(méi)有必須用 DOSBox 或虛擬機(jī)。這是系統(tǒng)層面的限制不是工具鏈的問(wèn)題。5. 避坑MASM 和 Link 在 Win10 下的 5 個(gè)典型翻車現(xiàn)場(chǎng)5.1 現(xiàn)象雙擊 MASM.exe 提示「此應(yīng)用無(wú)法在你的電腦上運(yùn)行」原因你拿到的是 16 位版本的 MASM.exeWin10 64 位移除了 NTVDM無(wú)法加載 16 位可執(zhí)行文件。解決換用 32 位版本的 MASM.exe。MASM32 包里的就是 32 位版本或者從 VS 的 VC\bin 目錄提取 ml.exe 加 /omf 參數(shù)替代。5.2 現(xiàn)象Link 報(bào)「invalid object file」或「unknown file type」原因目標(biāo)文件格式不匹配。ML.exe 默認(rèn)生成 COFF 格式而老版 Link.exe 5.60 只認(rèn) OMF 格式。解決編譯時(shí)加 /omf 參數(shù)ml /omf /c hello.asm?;蛘邠Q用支持 COFF 的新版 Link.exe但新版 Link 對(duì) 16 位程序支持不好容易出其他問(wèn)題。5.3 現(xiàn)象編譯通過(guò)但鏈接時(shí)報(bào)「cannot open file hello.obj」原因路徑里有空格或中文字符。Link.exe 對(duì)路徑解析很粗糙遇到空格會(huì)截?cái)唷=鉀Q把工作目錄移到純英文無(wú)空格路徑下比如 C:\asm\work。不要放在「我的文檔」或桌面這種帶空格的路徑里。5.4 現(xiàn)象運(yùn)行 hello.exe 閃退沒(méi)有任何輸出原因16 位 DOS 程序在 Win10 64 位下無(wú)法直接運(yùn)行系統(tǒng)加載后立即終止。解決用 DOSBox 運(yùn)行或者在 32 位 Win10 里跑。如果只是想驗(yàn)證編譯鏈接是否成功看到 hello.exe 生成即可不一定要運(yùn)行。5.5 現(xiàn)象MASM 報(bào)「A1006: invalid command-line option」原因命令行參數(shù)寫(xiě)錯(cuò)比如masm /c hello.asm里的 /c 不是 MASM 的參數(shù)那是 ML 的參數(shù)。解決查 MASM 的用法說(shuō)明直接masm回車看幫助。常用參數(shù)只有/Zi調(diào)試信息、/Fl生成列表文件等少數(shù)幾個(gè)。不確定就只用分號(hào)走默認(rèn)。6. 進(jìn)階用批處理一鍵完成編譯鏈接并驗(yàn)證每次手敲 masm 和 link 很煩我習(xí)慣在 work 目錄放一個(gè) build.batecho off REM build.bat - 一鍵編譯鏈接 16 位匯編程序 REM 用法: build.bat hello set NAME%1 if %NAME% ( echo 用法: build.bat ^源文件名^ exit /b 1 ) echo [1/2] 編譯 %NAME%.asm ... masm %NAME%.asm; if errorlevel 1 ( echo 編譯失敗請(qǐng)檢查錯(cuò)誤信息 exit /b 1 ) echo [2/2] 鏈接 %NAME%.obj ... link %NAME%.obj; if errorlevel 1 ( echo 鏈接失敗請(qǐng)檢查錯(cuò)誤信息 exit /b 1 ) echo 完成: %NAME%.exe這個(gè)批處理做了三件事檢查參數(shù)、編譯、鏈接每一步用 errorlevel 判斷是否成功。if errorlevel 1表示上一條命令返回值大于等于 1 就認(rèn)為失敗。MASM 和 Link 成功時(shí)返回 0失敗時(shí)返回非 0。用法是build.bat hello它會(huì)自動(dòng)找 hello.asm生成 hello.obj 和 hello.exe。如果編譯或鏈接出錯(cuò)會(huì)停下來(lái)并提示不會(huì)繼續(xù)往下跑。我還會(huì)加一個(gè)清理邏輯在編譯前刪掉舊的 obj 和 exe避免舊文件干擾if exist %NAME%.obj del %NAME%.obj if exist %NAME%.exe del %NAME%.exe放在編譯之前這樣每次都是干凈構(gòu)建。這個(gè)習(xí)慣是從 C 項(xiàng)目里帶過(guò)來(lái)的匯編項(xiàng)目文件少但舊 obj 導(dǎo)致鏈接到錯(cuò)誤代碼的情況也遇到過(guò)刪掉最省心。驗(yàn)證方法很簡(jiǎn)單改一下 hello.asm 里的字符串重新跑 build.bat然后用 DOSBox 運(yùn)行看輸出有沒(méi)有變。如果沒(méi)變說(shuō)明你跑的還是舊 exe檢查 build.bat 里的刪除邏輯有沒(méi)有生效。最后說(shuō)一個(gè)我自己的習(xí)慣每次換機(jī)器或重裝系統(tǒng)我會(huì)把 C:\asm 整個(gè)目錄打包存一份。里面就是 bin、include、lib、work 四個(gè)文件夾加起來(lái)不到 10MB。這樣下次不管是在 Win10 還是 Win11 上解壓、加 PATH、跑 build.bat五分鐘就能恢復(fù)匯編環(huán)境。比重新找安裝包、重新配路徑快得多。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取