基本概念(win32)彙編教程(轉)

heying1229發表於2007-07-28
基本概念(win32)彙編教程:

  我們先假設您已知道了如何使用MASM。如果您還不知道的話,請下載 win32asm.exe ,並請仔細研讀其中所附帶的文件資料。好,如果您已準備就緒,我們這就開始吧!

理論:

WIN32 程式執行在保護模式下的,保護模式的歷史可以追溯到 80286。而今 80286 已成為了歷史。所以我們將只把精力集中於 80386 及後續的X86 系列 CPU。Windows 把每一個 Win32 應用程式放到分開的虛擬地址空間中去執行,也就是說每一個應用程式都擁有其相互獨立的 4GB 地址空間,當然這倒不是說它們都擁有 4GB 的實體地址空間,而只是說能夠在 4GB 的範圍內定址。作業系統將會在應用程式執行時完成 4GB 的虛擬地址和實體記憶體地址間的轉換。這就要求編寫應用程式時必須格守 Windows 的規範,否則極易引起記憶體的保護模式錯誤。而過去的 Win16 記憶體模式下,所有的應用程式都執行於同一個 4GB 地址空間,它們可以彼此"看"到別的程式的內容,這極易導致一個應用程式破壞另一個應用程式甚至是作業系統的資料或程式碼。
和 16 位 Windows 下的把程式碼分成 DATA,CODE 等段的記憶體模式不同,WIN32 只有一種記憶體模式,即 FLAT 模式,意思是"平坦"的記憶體模式,再沒有 64K 的段大小限制,所有的 WIN32 的應用程式執行在一個連續、平坦、巨大的 4GB 的空間中。這同時也意味著您無須和段暫存器打交道,您可以用任意的段暫存器定址任意的地址空間,這對於程式設計師來說是非常方便的,這也使得用32位組合語言和用C語言一樣方便。 在Win32下程式設計,有許多重要的規則需要遵守。有一條很重要的是:Windows 在內部頻繁使用 ESI,EDI,EBP,EBX 暫存器,而且並不去檢測這些暫存器的值是否被更改,這樣當您要使用這些暫存器時必須先儲存它們的值,待用完後再恢復它們,一個最顯著的應用例子就是 Windows 的 CallBack 函式中。

內容:

下面的程式段是一個框架, 若您現在還不知道這些指令的確切意義的話,沒關係, 隨後我就會給大家詳細解釋。

.386
.MODEL Flat, STDCALL
.DATA

......
.DATA?

......
.CONST

......
.CODE

框架就這麼簡單,好,我現在就給您解釋:

.386
這是一個組合語言偽指令,他告訴編譯器我們的程式是使用80386指令集編寫的。您還可以使用 .486、.586, 但最的還是使用.386。對於每一種CPU有兩套幾乎功能相同偽指令: .386/.386P、 486/.486P、 586/.586P。 帶P的指令標明您的程式中可以用特權級指令。特權級指令是保留給作業系統的,如虛擬裝置驅動程式。在大多數時間,您的程式都無須執行在RING0層,故用不帶字尾P的偽指令已足夠了。

.MODEL FLAT,STDCALL
.MODEL 是用來指定記憶體模式的偽指令,在Win32下,只有一種記憶體模型,那就是FLAT。 STDCALL 告訴編譯器引數的傳遞約定。引數的傳遞約定是指引數傳達時的順序(從左到右或從右到左)和由誰恢復堆疊指標(呼叫者或被呼叫者)。在Win16下有兩種約定:C 和 PASCAL。C 約定規定引數傳遞順序是從右到左,即最右邊的引數最先壓棧,由呼叫者恢復堆疊指標。

例如:為呼叫函式 foo ( int first_param, int second_param, int third_param ); 按C約定的彙編程式碼應該是這樣的:

push [third_param]
push [second_param]
push [first_param]
call foo
add esp, 3 * 4 ;呼叫者自己恢復堆疊指標

PASCAL約定和C約定正好相反,它規定引數是從左向右傳遞,由被呼叫者恢復堆疊。Win16採用了PASCAL約定, 因為PASCAL約定產生的程式碼量要小。當不知道引數的個數時,C約定特別有用。如在函式wsprintf () 中, wsprintf預先並不知道要傳遞幾個引數,所以它不知道如何恢復堆疊。STDCALL是C約定和PASCAL約定的混合體,它規定引數的傳遞是從右到左,恢復堆疊的工作交由被呼叫者。Win32只用STDCALL約定,但除了一個特例,即:wsprintf。

.DATA .DATA? .CONST .CODE
上面的四個偽指令是"分段"(SECTION)偽指令。我們上面剛講過Win32下沒有"段"(SEGMENT)的概念,但是您可以把您的程式分成不同的"分段", 一個"分段"的開始即是上一個"分段"的結束。WIN32中只有兩種性質的"分段":DATA和CODE。
其中DATA"分段"又分為三種:
.DATA 其中包括已初始化的資料。
.DATA? 其中包括未初始化的資料。比如有時您僅想預先分配一些記憶體但並不想指定初始值。使用未初始化的資料的優點是它不佔據可執行檔案的大小,如:若您要在 .DATA? 段中分配10,000位元組的空間,您的可執行檔案的大小無須增加10,000位元組,而僅僅是要告訴編譯器在裝載可執行檔案時分配所需位元組。
.CONST 其中包括常量定義。這些常量在程式執行過程中是不能更改的。 應用程式並不需要以上所有的三個"分段", 可以根據需要進行定義。
.CODE 這是程式碼"分段"。

[@more@]

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

相關文章