Win32彙編的環境和基礎(轉)

heying1229發表於2007-07-28
Win32彙編的環境和基礎:

  1.32位環境簡介

   在Dos下編彙編程式,我們可以管理系統的所有資源,我們可以改動系統中所有的記憶體,如自己改動記憶體控制塊來分配記憶體,自己修改中斷向量表來截獲中斷等,對其他操作也是如此,如我們對鍵盤埠直接操作就可以把鍵盤遮蔽掉,可以這樣來描述Dos系統:系統只有一個特權級別,在程式設計上講,任何程式和作業系統都是同級的,所以在Dos下,一個編得不好的程式會影響其他所有的程式,如一個程式把鍵盤口中斷關掉了,所有程式就都不能從鍵盤獲得鍵入的資料,直到任何一個程式重新開啟鍵盤為止,一個程式陷入死迴圈,也沒有其他程式可以把它終止掉。Dos下的程式設計思路是“單任務”的,你只要認為你的程式會按照你的流程一步步的執行下去,不必考慮先後問題(當然程式可能會被中斷打斷,但你可以認為它們會把環境恢復,如果中斷程式沒有把環境恢復,那是他們的錯)。

   在記憶體管理方式上,Dos彙編和Win32彙編也有很多的不同:Dos工作在真實模式下,我們可以定址1M的記憶體,定址時透過段暫存器來制定段的初始地址,每個段的大小為64K,超過1M的部分,就只能把他作為XMS使用,也就是說,只能用作資料存放使用而無法在其中執行程式。

   而Windows在保護模式下執行,這裡所有的資源對應用程式來說都是被“保護”的:程式在執行中有級別之分,只有作業系統工作在最高階--0級中,所有應用程式都工作在3級中(Ring3),
在Ring3中,你無法直接訪問IO埠,無法訪問其他程式執行的記憶體,連向程式自己的程式碼段寫入資料都是非法的,會在Windows的螢幕上冒出一個熟悉的藍螢幕來。只有對Ring0的程式來說,系統才是全開放的。

   在記憶體方面,Windows使用了處理器的分頁機制,使得對應用程式來說,所有的記憶體都是“平坦”的,你不必用一個段暫存器去指定段的地址,因為在保護模式下,段暫存器的含義是不同的(可以參見80386手冊方面的書籍),你可以直接指定一個32位的地址來定址4GB的記憶體。

   在程式結構方面,Windows程式也有很大的不同,它是“基於訊息”的,你可以想象這樣一個常見的Windows視窗,上面有幾個按鈕,如果你用Dos程式設計的思路去考慮,你會發現實現它很困難:滑鼠移動到視窗邊緣時拖動會改變視窗大小,滑鼠點選按鈕時再做要做的事,你會發現,你的程式自開始執行後就在等待,你不知道滑鼠先會點什麼地方,實際上你是在等待所有可能的事情的發生。而在Dos下,你可以只顧自己先執行,需要使用者輸入時,再停下來,你不輸入我就不再執行,而且,我讓你輸入資料A你就不能輸入資料B。
好了,言歸正傳,因為以上是Win32程式設計的基礎,無論對Win32彙編還是VC++,它們都是一樣的,下面我們來看看有關Win32彙編的內容。
2.Win32ASM編譯器

   Win32ASM的編譯器最常用的有兩種:Borland公司的Tasm5.0和Microsoft的Masm6.11以上版本,兩種編譯器各有自己的優缺點,Tasm帶了一個不大不小的Import庫,而Masm沒有帶,但Masm在程式碼的最佳化上面好象比Tasm做得好,但它卻不帶Import庫。看來使用哪一種編譯器還是比較難選擇的,但Steve
Hutchesson給了我們一個答案,他為Masm建立了一個很全的Import庫,基本上包括了Windows絕大部分的Api函式,這些庫、include檔案和其他還有Masm6.14版本一起做成了一個 Masm32編譯器 -- Masm32V5。這樣一來,我們用匯編程式設計就象用C一樣方便。

   因為有了Masm32V5,所以就我個人而言,我推薦使用Masm作為Win32ASM的編譯,但Masm和Tasm的宏語法有很多的不同,我的這個教程是以Masm格式寫的。
3.Masm32的環境設定

   在Win32程式設計中,由於Windows有很多的資料結構和定義,這些都放在include檔案中,還有連線時要用到Import庫(通俗的講就是Windows提供的DLL檔案中的函式列表,也就是告訴程式到哪裡去呼叫API函式),這些都放在include
和lib目錄中。我們在編譯時要指定以下的系統環境:
set include=Masm32v5Include
set lib=Masmv5lib
set path=Masmv5Bin
   這樣編譯器就會到正確的路徑中去找 include 檔案和 lib 檔案。你可以自己在 autoexec.bat
檔案中加上以上語句,為了產生Windows的PE格式的執行檔案,在編譯和連線中要指定相應的引數:
編譯: Ml /c /coff 檔名.asm
連線: Link /SUBSYSTEM:WINDOWS OBJ檔名.obj 資原始檔名.res
   為了不在每次編譯時都要打這麼多的引數,我們可以用 nmake 檔案來代為執行,nmake 是程式碼維護程式,他會檢查 .asm .obj .exe .res
等檔案的時間,如果你更新了源程式,他會自動執行編譯程式或連線程式產生相應的檔案。你可以在檔名為 makefile
的檔案中指定使用的編譯器和連線程式以及相應的引數,下面是一個 makefile 檔案的例子:
NAME = Clock
OBJS = $(NAME).obj
RES = $(NAME).res
$(NAME).exe: $(OBJS) $(RES)
Link /DEBUG /SUBSYSTEM:WINDOWS $(OBJS) $(RES)
$(RES): $(NAME).rc
Rc $(NAME).rc
.asm.obj:
Ml /c /coff $(NAME).asm
檔案告訴 nmake程式,程式名為 clock,產生 clock.exe 檔案需要 clock.obj和 clock.res 檔案,而產生 clock.res
檔案需要 clock.rc 檔案,產生 clock.obj 檔案要用到 clock.asm 檔案,至於是否需要執行 ml, link 和
rc,程式會根據檔案的時間自動判斷。

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10172717/viewspace-928827/,如需轉載,請註明出處,否則將追究法律責任。

相關文章