(譯)win32asm教程-5 (轉)

gugu99發表於2008-01-12
(譯)win32asm教程-5 (轉)[@more@] 

6.0 結構:namespace prefix = o ns = "urn:schemas--com::office" />

原始檔被分成了幾個部分。這些部分是code,data,未初始化data,constants,re和relocations,資源部分是資原始檔建立的,後面會有更多的討論。Relocation部分對我們不重要(它包含了使PE-loader可以在的不同的位置裝載入的資訊)。重要的部分是code,data,未初始化data和constants。可能你已經猜到,code部分包含了程式碼。Data裝有資料,並有讀寫。整個data部分被包括在exe檔案並可以用資料初始化。

未初始化data在啟動時沒有內容,甚至沒有包括在exe檔案本身。它只是由“分配”的一部分記憶體。這部分也有讀寫許可權。Constants和data部分一樣,但只讀。雖然這部分可用作常熟,但把常熟定義在包含檔案中更簡單也更快捷,並用作直接數值。

6.1 Section indicators(部分代表符)

在你的原始檔(*.asm)中,你可以用部分識別符號定義部分:

.code;code部分由此開始
.data;data部分由此開始
.data?;未初始化data 部分由此開始
.const;constants部分由此開始

可檔案(*.exe,*.dll和其他)是(在中)可移植執行格式(PE),我不會詳細的討論它但是有幾點是重要的。部分(Sections)用一些屬性定義在PE頭中:

Section名,RVA,offset,原始大小,虛擬大小和標誌。Rva(相對虛擬地址)是將要裝入的section部分相對記憶體地址。這裡相對的意思是相對於程式載入的基地址。這個地址也在PE頭中,但可以由PE-loader改變(使用relocation部分)。Offset是初始化資料所在的exe檔案本身的原始offset。虛擬大小是程式在記憶體中將達到的大小。標誌是讀/寫/可執行等。

3.  2例子

這有一個示例程式:

.data
Number1 dd 12033h
Number2 dw 100h,200h,300h,400h
Number3 "blabla",0

.data?
Value dd ?

.code
mov eax, Number1
mov ecx, offset Number2
add ax, ptr [ecx+4]
mov Value, eax

這個程式不能編譯但沒關係。

在你的匯序中,你放入“部分”中的所有東西都會進入exe檔案而且當程式被載入記憶體時,位於某個記憶體地址。在上面的data部分,有3個標籤:Number1, Number2, Number3。這些標籤會儲存它們在程式中的offset因而你可以在你的程式中使用它們來指示位置。

DD直接把一個dword放在那,DW是Word而DB是byte。你也可以用db放字串,因為它實際上是一串byte值。在例子中,data部分會變成記憶體中的這樣:

33,20,01,00,00,01,00,02,00,03,00,04,62,6c,61,62,6c,61,00(均為十六進位制值)

(每個值位一byte)

我給其中的一些數字上了色。Number1指向byte 33所在的記憶體地址,Number2指向紅色00的位置,Number3是綠色的62。現在,如果你在你的程式中這麼寫:

mov eax, Number1

它實際意為:

mov ecx, dword ptr[12033h所在的記憶體地址]

但這樣:

mov ecx, offset Number1

意為:

mov ecx, 12033h所在的記憶體地址

在第一個例子中,ecx會得到Number1的記憶體地址的值。在第二個中,ecx會稱為記憶體地址(offset)本身。下面的兩個例子有相同的效果:

(1)
mov ecx, Number1

(2)
mov ecx, offset Number1
mov ecx, dword ptr [ecx]
( or mov ecx, [ecx])

現在讓我們回到前面的例子中:

.data
Number1 dd 12033h
Number2 dw 100h,200h,300h,400h
Number3 db "blabla",0

.data?
Value dd ?

.code
mov eax, Number1
mov ecx, offset Number2
add ax, word ptr [ecx+4]
mov Value, eax

標籤可以使用像Number1,Number2和Number3等值,但它啟動時包含0。因為它在未初始化data部分。這樣的優點是,你在.data?中定義的所有東西不在可執行檔案中而在記憶體中。

.data?
ManyBytes1 db 5000 dup (?)

.data
ManyBytes2 db 5000 dup (0)

(5000dup意為:5000個副本。值db 4,4,4,4,4,4,4和值db 7dup(4)一樣)

ManyBytes1不會在檔案本身,只是5000個預分配在記憶體中的位元組。但Manybytes2會在可執行檔案中使檔案變大5000個位元組。雖然你的檔案會包含5000個零,但並沒有什麼用。

Code部分被彙編(翻譯為原始程式碼)並放入可執行檔案中去(當然載入後在記憶體中)。


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

相關文章