前言
前面已經提到了為什么從MASM轉到NASM,並且也簡單的介紹了一下MASM和NASM在偽指令和程序結構上的差異,現在就來搭建一下NASM的編譯、開發、調試環境吧。
參考資料:
http://blog.csdn.net/duweix/article/details/19911967
http://blog.csdn.net/cashey1991/article/details/6773927
http://www.mouseos.com/assembly/nasm02.html
http://www.linuxidc.com/Linux/2013-01/78271.htm
WINDOWS
nasm的安裝配置
nasm的安裝包可以在nasm的官方網站下載到最新的版本,注意安裝的時候最好是右鍵管理員安裝。
這之后你可以在CMD中輸入 nasm -v 查看nasm的版本,我安裝完之后nasm命令是未識別的,所以我手動添加了一下環境變量(如何添加環境變量請自行百度)
環境變量配置正確之后在cmd中輸入 nasm -v 就可以看到nasm 顯示了它的版本信息。
這個時候已經可以使用nasm直接編譯匯編代碼的,如果只是想編譯二進制的代碼那么其實這個時候環境搭建就完成了,但是純二進制的代碼在windows 10 上運行調試都很麻煩的。我能想到的一個辦法就是以前提到過的,裝個虛擬機用磁盤工具寫到引導扇區,開機直接運行但是這樣調試困難。
所以還是編譯成exe在windows上直接運行吧,這樣就可以借助各種調試工具了。但是編譯成exe其實也有一個麻煩的地方就是好多中斷不能使用, 以后CPU的內存管理啊,cpu的模式切換等等都沒法使用,並且屏幕輸出很麻煩。但是沒關系,先編譯成exe把程序邏輯調好,其他的只是接口的調用而已很方便集成的。
nasm可以通過 -f 指令指定要匯編的目標平台,可以使用 nasm -hf 查看支持的平台模式,默認是純二進制的
所以你要編譯純二進制的文件的話,只需使用如下命令
nasm xx.asm
windows 32 為進程
nasm -f win32 helloworld.asm
windows 64 為進程
nasm -f win64 helloworld.asm
visual stdio的安裝
沒辦法啊要編譯windows的應用vs是躲不過去的, 我安裝的是最新的vs2017.怎么裝請自行百度咯。
編譯調試
如何編譯成exe參考 http://blog.csdn.net/duweix/article/details/19911967
主要是兩條命令
1. 先將asm變成.obj文件
nasm -f win32 helloworld.asm
2. 將obj文件和c庫鏈接成exe (cl.exe 是visual stduio的鏈接器在visual studio路徑下的某個目錄,或者也可以啟動VS 的CMD 直接調用)
cl.exe helloworld.obj /link libcmt.lib
鏈接博文z中的asm其實是調用了c的print函數在控制台輸出了內容。博文中的示例匯編代碼 我在公司的vs2008 環境下編譯沒問題,但是回家用vs2017就出現了找不到鏈接地址的情況。不知道是不是庫不對。反正我沒細究。不用print就是。
編譯成的exe怎么調試呢?當然使用vs2017啦,當然也可以用windbg,厲害一點的用IDA也是可以的,反正就是各種反匯編調試工具。應為我們本來就是寫的匯編,反匯編出來的結果和我們寫的代碼是一模一樣的,所以調試很方便。
這里說一下vs2017具體的調試步驟
文件 =》打開 =》 項目
直接打開exe
如下圖
然后右鍵 =》調試=》 單步調試
他可能會提示你沒找到PDB文件或者沒有源代碼什么什么的,沒關系按確定,然后把反匯編窗口顯示出來
你也可以把寄存器窗口顯示出現,這樣就能看到寄存器的變化。
注意一點: 調試一開始可能不是停在了你匯編開始的位置,而是停在了C庫的某個位置,這個時候你 F10 運行幾步就會到你代碼的開始位置了。
nasm with vs2017
前面的步驟已經可是開發編譯調試了,但是你寫匯編可能用一個文本編輯器 ,編譯鏈接手動敲命令,vs只有在調試的時候才用到太可惜了。
接下來就是我自己摸索出來的在vs2017集成環境中開發編譯調試匯編程序。
1. 新建一個 C++ 空項目
2. 右鍵屬性 =》常規 =》配置項目改成 生成文件
3. 然后選擇NMake標簽 生成命令寫上nmake,沒錯就是利用了windows的nmake工具,windows的nmake和linux下的make是一樣的東西,所以同樣也需要一個makefile
4. 新建一個makefile文件,內容如下
# 目標程序的名稱,就是定義各一個宏定義,用來指定程序的名字,所以這個 hello.exe 是可以任意替換的,所編寫啥 EXE = hello.exe
# 需要用到的模塊 這也是定義個一個宏變量OBJS, hello.obj 實際指的是 hello.asm 匯編文件
# 所以如果你的匯編文件叫 helloword.asm 你就寫 helloword.obj
# 如果你的程序需要多個匯編文件也是支持的名字用空格隔開即可,也可以用 \ 表示換行,比如
#OBJ = hello.obj\
# print.obj\
# input.obj
OBJS = hello.obj
#編譯的平台32?64
FORMAT = win32 # 鏈接命令, 就是鏈接上面所指定的所有的obj,這個不用改 $(EXE) :$(OBJS) cd Debug cl.exe $(OBJS) /link libcmt.lib # 編譯.asm成.obj,這是指定obj由asm編譯而來,並是喲個下邊的編譯指令,所以可以看出我這里編譯的都是32位的 .asm.obj: nasm -f $(FORMAT) $< -o Debug\$*.obj #清除臨時文件 clean : del*.obj
具體makefile的語法規則可參考前言中給出的鏈接,上面這個是我研究了好久好不容易寫出來的makefile,當然也只是研究了個皮毛出來而已。大家將就着試試。
5. 接下來就可以按F5運行調試,記得打開 反匯編窗口和寄存器窗口。
這是我寫的一個例子: https://files.cnblogs.com/files/alwaysking/asm.zip
LINUX
linux下沒啥繼承環境,所以基本就只有敲命令咯
參考: http://www.linuxidc.com/Linux/2013-01/78271.htm
1. 先將匯編文件編譯成.o文件對應的就是windows下的.obj,注意linux32要要選擇編譯成 elf32格式 64位要選擇編譯成 elf64
nasm -f elf32 hello.asm
2. 使用GCC將.o文件編譯成可執行文件
gcc -o hello hello.o
make是linux下的項目編譯工具,我也簡單的寫了一個makefile文件
# 目標名稱
EXE=hello
# 需要用到的模塊 這也是定義個一個宏變量OBJS, hello.obj 實際指的是 hello.asm 匯編文件
# 所以如果你的匯編文件叫 helloword.asm 你就寫 helloword.obj
# 如果你的程序需要多個匯編文件也是支持的名字用空格隔開即可,也可以用 \ 表示換行,比如
OBJS = hello.o
#編譯的平台32?64
FORMAT = elf32
# 連接命令這個不用改
All:$(OBJS) gcc -o $(EXE)
# 編譯對應的asm成.o文件,這個也不用改
$(OBJS) $(OBJS): %.o: %.asm
nasm -f $(FORMAT) $< -o $@
# 清理操作
.PHONY:clean
clean:
rm -rf *.o Test @echo "Clean done!"