第 8 章 : 進階程序

50
第 8 第 : 第第第第

Upload: hammer

Post on 21-Jan-2016

79 views

Category:

Documents


0 download

DESCRIPTION

第 8 章 : 進階程序. 章節概要. 區域變數 堆疊參數 堆疊框 遞迴 建立多模組程式. 區域指令. 一個區域變數在一個程序裡面被產生使用,而且破壞 區域指令宣布一連串的區域變數 立刻遵循 PROC 指令 每個變數被分配一個類型 語法 : LOCAL varlist 例題 :. MySub PROC LOCAL var1:BYTE, var2:WORD, var3:SDWORD. 區域變數. 例題 :. LOCAL flagVals[20]:BYTE; array of bytes - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第  8  章 : 進階程序

第 8 章 : 進階程序

Page 2: 第  8  章 : 進階程序

Web site Examples 2

章節概要章節概要

• 區域變數 • 堆疊參數 • 堆疊框• 遞迴• 建立多模組程式

Page 3: 第  8  章 : 進階程序

Web site Examples 3

區域指令 區域指令 • 一個區域變數在一個程序裡面被產生使用,而且

破壞• 區域指令宣布一連串的區域變數

• 立刻遵循 PROC 指令• 每個變數被分配一個類型

• 語法 :LOCAL varlist

例題 :

MySub PROCLOCAL var1:BYTE, var2:WORD, var3:SDWORD

Page 4: 第  8  章 : 進階程序

Web site Examples 4

區域變數 區域變數

LOCAL flagVals[20]:BYTE ; array of bytes

LOCAL pArray:PTR WORD ; pointer to an array

myProc PROC, ; procedurep1:PTR WORD ; parameterLOCAL t1:BYTE, ; local variablest2:WORD,t3:DWORD,t4:PTR DWORD

例題 :

Page 5: 第  8  章 : 進階程序

Web site Examples 5

MASM-MASM- 生成代碼生成代碼 (1 of 2)(1 of 2)

BubbleSort PROCLOCAL temp:DWORD, SwapFlag:BYTE. . .ret

BubbleSort ENDP

BubbleSort PROCpush ebpmov ebp,espadd esp,0FFFFFFF8h ; add -8 to ESP. . .mov esp,ebppop ebpret

BubbleSort ENDP

MASM 產生下列的編碼 :

Page 6: 第  8  章 : 進階程序

Web site Examples 6

MASM-MASM- 生成代碼生成代碼 (2 of 2)(2 of 2)

堆疊的圖表為 BubbleSort 程序構成:

Page 7: 第  8  章 : 進階程序

Web site Examples 7

堆疊參數 堆疊參數

• 暫存器和堆疊參數比較• INVOKE 指引• PROC 指引• PROTO 指引• 通過按價值計算比路過參考• 參數分類• 例子:交換二個整數• 問題解析訣竅

Page 8: 第  8  章 : 進階程序

Web site Examples 8

暫存器和堆疊參數比較暫存器和堆疊參數比較

• 暫存器參數需要把一個暫存器獻給每個參數。• 想像呼叫 DumpMem 程序的二個可能方法。清楚地

其次比較容易:

pushadmov esi,OFFSET arraymov ecx,LENGTHOF arraymov ebx,TYPE arraycall DumpMempopad

push OFFSET arraypush LENGTHOF arraypush TYPE arraycall DumpMem

Page 9: 第  8  章 : 進階程序

Web site Examples 9

INVOKE INVOKE 指引指引

• 那喚起指令是英代爾的呼叫指令的一個有力的替換讓你通過多個爭論

• 語法 :INVOKE 程序名稱 [ 引數清單 ]

• ArgumentList 是一個傳遞給程序的可選用引數清單• Arguments 能是 :

• 立即的值和整數語法• 變數名字• 位址和 ADDR 語法• 暫存器名字

Page 10: 第  8  章 : 進階程序

Web site Examples 10

INVOKE INVOKE 例題例題

.databyteVal BYTE 10wordVal WORD 1000h.code

; direct operands:INVOKE Sub1,byteVal,wordVal

; address of variable:INVOKE Sub2,ADDR byteVal

; register name, integer expression:INVOKE Sub3,eax,(10 * 20)

; address expression (indirect operand):INVOKE Sub4,[ebx]

Page 11: 第  8  章 : 進階程序

Web site Examples 11

ADDRADDR 運算子運算子

.datamyWord WORD ?.codeINVOKE mySub,ADDR myWord

• 會根據程式的記憶體模式所要求,來傳遞 near 指標或 far 指標。

• 小的模型:回復 16 位元補償• 大的模型 : 回復 32 位元分割/補償• 平坦的模型 : 回復 32 位元補償• 簡單例題 :

Page 12: 第  8  章 : 進階程序

Web site Examples 12

PROC PROC 指引指引

• PROC 指令用一個命名的參數可選擇目錄宣布一個程序 .

• 語法 :label PROC paramList

• paramList 是被逗點分開的一連串的參數。每個參數有下列的語法 :

paramName:type

樣式必須或是標準 ASM 類型 ( BYTE , SBYTE , WORD , etc )之一 , 否則它可能是對這些類型之一的一個指標 .

Page 13: 第  8  章 : 進階程序

Web site Examples 13

PROC PROC 例題例題 (1 of 3)(1 of 3)

AddTwo PROC,val1:DWORD, val2:DWORD

mov eax,val1add eax,val2ret

AddTwo ENDP

• AddTwo 程序在 EAX 接受二個整數而且回復他們的總數 .

• C++ 程式典型地在 EAX 回復來自功能的 32 位元整數。

Page 14: 第  8  章 : 進階程序

Web site Examples 14

PROC PROC 例題例題 (2 of 3)(2 of 3)

FillArray PROC,pArray:PTR BYTE, fillVal:BYTEarraySize:DWORD

mov ecx,arraySizemov esi,pArraymov al,fillVal

L1: mov [esi],alinc esiloop L1ret

FillArray ENDP

FillArray 接受對位元組的排列一個指標,一個位元組填滿將到排列的每種元素 , 和排列的大小被複制的值。

Page 15: 第  8  章 : 進階程序

Web site Examples 15

PROC PROC 例題例題 (3 of 3)(3 of 3)

ReadFile PROC,pBuffer:PTR BYTELOCAL fileHandle:DWORD. . .

ReadFile ENDP

Swap PROC,pValX:PTR DWORD,pValY:PTR DWORD. . .

Swap ENDP

Page 16: 第  8  章 : 進階程序

Web site Examples 16

PROTO PROTO 指引指引

• 產生一個程序原型• 語法 :

• label PROTO paramList

• 每個程序順道拜訪那喚起指令一定要有一個原型• 一種完全的程序定義也能視為 ownprototype

Page 17: 第  8  章 : 進階程序

Web site Examples 17

PROTO PROTO 指引指引

• 標準結構: PROTO 在程式項目表的頂端出現,在編碼分割中INVOKE 出現,和程序履行稍後在程式中發生

MySub PROTO ; procedure prototype

.codeINVOKE MySub ; procedure call

MySub PROC ; procedure implementation..

MySub ENDP

Page 18: 第  8  章 : 進階程序

Web site Examples 18

PROTO PROTO 例題例題

• 為 ArraySum 程序原型,顯示它的參數目錄:

ArraySum PROTO,ptrArray:PTR DWORD, ; points to the arrayszArray:DWORD ; array size

Page 19: 第  8  章 : 進階程序

Web site Examples 19

經過價值經過價值• 當一個程序引數被經過價值的時候,複製 16 位元或

32 位元整數是推動堆疊。• 例題 :

.datamyData WORD 1000h.codemain PROC

INVOKE Sub1, myData

push myDatacall Sub1

MASM 產生下列的編碼 :

Page 20: 第  8  章 : 進階程序

Web site Examples 20

參考經過參考經過

• 當一個引數被經過參考的時候,它的位址是推動堆疊 . 例題 :

.datamyData WORD 1000h.codemain PROC

INVOKE Sub1, ADDR myData

push OFFSET myDatacall Sub1

MASM 產生下列的編碼 :

Page 21: 第  8  章 : 進階程序

Web site Examples 21

參數分類 參數分類 • 輸入: 輸入參數即為,由呼叫者程式傳遞給被呼叫程序的資料。

我們不期望被呼叫程序修改 到對應的參數變數,即使它這麼做了,修改的效果也應該只侷限在程序本身以內。

• 輸入 - 輸出: 輸入 - 輸出參數與輸出參數幾乎完全相同,它們的差異點是: 被呼叫的程序會預 期,由參數所參照的變數將含有一些資料。

• 輸出: 當呼叫者程式傳遞某個變數的位址給一個程序時,就會建立起輸出參數。 程序可以使 用這個位址找到該變數,並且指定資料給該變數。

Page 22: 第  8  章 : 進階程序

Web site Examples 22

範例: 交換兩個整數 範例: 交換兩個整數

Swap PROC USES eax esi edi,pValX:PTR DWORD, ; pointer to first integerpValY:PTR DWORD ; pointer to second integer

mov esi,pValX ; get pointersmov edi,pValYmov eax,[esi] ; get first integerxchg eax,[edi] ; exchange with secondmov [esi],eax ; replace first integerret

Swap ENDP

使用到的 Swap 程序具有兩個 輸入 - 輸出參數,其名稱分別為 pValX 和 pValY ,這兩個參數所含有的,就是要進行交換 的資料的位址:

Page 23: 第  8  章 : 進階程序

Web site Examples 23

除錯的訣竅 除錯的訣竅

• 當他們被一個程序修正的時候,儲存而且回復暫存器 .• 除了一個暫存器回復產生一個函數

• 當使用 INVOKE 的時候,小心通過一個指標給正確的資料類型 .

• 舉例來說, MASM 不能夠區別一個 DWORD 引數和一個 PTR 位元組引數。

• 不要傳遞給它立即值引數 .• 遵從它的位址將或許引起一種普通保護的過失。

Page 24: 第  8  章 : 進階程序

Web site Examples 24

堆疊框 堆疊框

• 記憶體模式• 語言 Specifiers• 明確准入堆疊參數• 經過引數的參考• 創造區域變數

Page 25: 第  8  章 : 進階程序

Web site Examples 25

堆疊框 堆疊框

• 知道當做一筆啟動記錄• 堆疊的區域對於一個程序的回復位址留存,經過參數,

保存了暫存器,和區域變數• 藉著下列步驟產生 :

• 呼叫子常式,因而導致子常式的返回位址被壓進堆疊中 .

• EBP 設定等於 ESP 。 從這個時候開始, EBP 的作用是當作所有子常式參數的基底參考。 .

• 如有任何區域變數存在,則我們可將 ESP 減去某值,以便在堆疊中保留區域變數的儲存空間。

Page 26: 第  8  章 : 進階程序

Web site Examples 26

記憶體模式記憶體模式

• 一個程式的記憶體模式決定數字和編碼和資料分割的大小 .

• 實體位址模式下的程式 tiny, small, medium, compact, large, 和 huge 模式 .

• 在保護模式下的程式,使用的是 flat 記憶體 .

Small model: code < 64 KB, data (including stack) < 64 KB. All offsets are 16 bits.

Flat model: single segment for code and data, up to 4 GB. All offsets are 32 bits.

Page 27: 第  8  章 : 進階程序

Web site Examples 27

.MODEL .MODEL 指令指令

• 模式的指定符一個程式的記憶體模式和模式的選擇。(語言-指定符)

• 語法 :.MODEL memorymodel [,modeloptions]

• 記憶體模式可能是下列各項之一 :

• tiny, small, medium, compact, large, huge, 或 flat

• 模是選項包括語言指定符 :

• 程序取名方案• 參數經過慣例

Page 28: 第  8  章 : 進階程序

Web site Examples 28

語言指定符語言指定符

• C:• 指定符會要求程序引數,以相反順序壓進堆疊 (向右離

開 )• 呼叫程式清除堆疊

• pascal• 程序引數順向壓進 (由左至右 )• 呼叫程式清除堆疊

• stdcall• 指定符會要求程序引數,以相反順序壓進堆疊 (由右至

左 )• 呼叫程式清除堆疊

Page 29: 第  8  章 : 進階程序

Web site Examples 29

明確經過堆積參數明確經過堆積參數

• 一個程序能明確取得使用來自 EBP1 的常數彌補的堆疊參數 .

• 例題 : [ebp + 8]

• 因為它支撐堆疊結構的基礎位址,所以 EBP 時常被稱為基礎的指標或者結構指標 .

• EBP 不在程序的時候改變值 .

• 當一個程序回復時, EBP 一定要對它的最初值回復 .

Page 30: 第  8  章 : 進階程序

Web site Examples 30

堆疊框例子堆疊框例子 (1 of 2)(1 of 2)

.datasum DWORD ?.code

push 6 ; second argumentpush 5 ; first argumentcall AddTwo ; EAX = summov sum,eax ; save the sum

AddTwo PROCpush ebpmov ebp,esp..

Page 31: 第  8  章 : 進階程序

Web site Examples 31

堆疊框例題堆疊框例題 (2 of 2)(2 of 2)

AddTwo PROCpush ebpmov ebp,esp ; base of stack framemov eax,[ebp + 12] ; second argument (6)add eax,[ebp + 8] ; first argument (5)pop ebpret 8 ; clean up the stack

AddTwo ENDP ; EAX contains the sum

Page 32: 第  8  章 : 進階程序

Web site Examples 32

習題習題 . . .. . .

• 產生一個叫做減去來自第二個的第一個引數不同的程序。下列各項是一個樣本呼叫 :

push 14 ; first argument

push 30 ; second argument

call Difference ; EAX = 16

Difference PROCpush ebpmov ebp,espmov eax,[ebp + 8] ; second argumentsub eax,[ebp + 12] ; first argumentpop ebpret 8

Difference ENDP

Page 33: 第  8  章 : 進階程序

Web site Examples 33

參考經過引數參考經過引數 (1 of 2)(1 of 2)

• ArrayFill 程序,可使一個陣列填入由 16 位元整數所 組成的擬隨機數列。

• 第一 個引數利用參考的方式加以傳遞,第二個則使用傳值的方式傳遞。 以下是一個示範呼叫:

.datacount = 100array WORD count DUP(?).code

push OFFSET arraypush COUNTcall ArrayFill

Page 34: 第  8  章 : 進階程序

Web site Examples 34

參考經過引數參考經過引數 (2 of 2)(2 of 2)

ArrayFill PROCpush ebpmov ebp,esppushadmov esi,[ebp+12]mov ecx,[ebp+8]..

ESI 指向排列的開始,因此,使用一個迴路取得每種排列元素是容易的 . 顯示完全的計畫 .

ArrayFill 能參考排列不知道排列的命名 :

Page 35: 第  8  章 : 進階程序

Web site Examples 35

LEALEA 指令指令

• LEA 指令用於回傳間接運算元的位移 . • 彌補運算能唯一的回復常數彌補 .

• 當獲得堆疊參數或區域變數的彌補時, 需要 LEA .舉例來說 :

CopyString PROC,count:DWORDLOCAL temp[20]:BYTE

mov edi,OFFSET count ; invalid operandmov esi,OFFSET temp ; invalid operandlea edi,count ; oklea esi,temp ; ok

Page 36: 第  8  章 : 進階程序

Web site Examples 36

產生區域變數產生區域變數

• 為了要明確地產生區域變數,減去來自 ESP 總數大小 .

• 下列的例子產生並且設定二個 32 位元區域變數初值 : (我們稱它們為 locA 和 locB )

MySub PROCpush ebpmov ebp,espsub esp,8mov [ebp-4],123456h ; locAmov [ebp-8],0 ; locB..

Page 37: 第  8  章 : 進階程序

Web site Examples 37

遞迴 遞迴

• 遞迴是甚麼 ?• 遞迴計算總數• 計算階乘

Page 38: 第  8  章 : 進階程序

Web site Examples 38

遞迴是甚麼遞迴是甚麼 ??

• 程序產生當 . . .• 一個程序呼叫本身• 程序 A 呼叫程序 B,依次呼叫程序 A

• 使用一個圖表在每個節是程序和每個邊緣是一個程序呼叫,遞迴形成一個周期 :

Page 39: 第  8  章 : 進階程序

Web site Examples 39

遞迴計算總數遞迴計算總數

CalcSum PROCcmp ecx,0 ; check counter valuejz L2 ; quit if zeroadd eax,ecx ; otherwise, add to sumdec ecx ; decrement countercall CalcSum ; recursive call

L2: retCalcSum ENDP

CalcSum 程序遞迴計算整數排列的總數 : ECX = count. Returns: EAX = sum

Stack frame:顯示完全計畫

Page 40: 第  8  章 : 進階程序

Web site Examples 40

計算階乘計算階乘 (1 of 3)(1 of 3)

int function factorial(int n){

if(n == 0) return 1;else return n * factorial(n-1);

}

5! = 5 * 4!

4! = 4 * 3!

3! = 3 * 2!

2! = 2 * 1!

1! = 1 * 0!

0! = 1

(base case)

1 * 1 = 1

2 * 1 = 2

3 * 2 = 6

4 * 6 = 24

5 * 24 = 120

1 = 1

recursive calls backing up

這一個功能計算整數 n 的階乘。 n 的新數值在每個堆疊框中被保存 :

As each call instance returns, the product it returns is multiplied by the previous value of n.

Page 41: 第  8  章 : 進階程序

Web site Examples 41

計算階乘計算階乘 (2 of 3)(2 of 3)

Factorial PROCpush ebpmov ebp,espmov eax,[ebp+8] ; get ncmp eax,0 ; n < 0?ja L1 ; yes: continuemov eax,1 ; no: return 1jmp L2

L1: dec eaxpush eax ; Factorial(n-1)call Factorial

; Instructions from this point on execute when each; recursive call returns.

ReturnFact:mov ebx,[ebp+8] ; get nmul ebx ; ax = ax * bx

L2: pop ebp ; return EAXret 4 ; clean up stack

Factorial ENDP

看計畫項目表

Page 42: 第  8  章 : 進階程序

Web site Examples 42

計算階乘計算階乘 (3 of 3)(3 of 3)

假如我們想要計算 12!

這一個圖表顯示第一個少數堆疊框架

藉著對階乘的遞迴呼叫產生

每個遞迴的呼叫使用 12個位元組的堆疊空間 .

Page 43: 第  8  章 : 進階程序

Web site Examples 43

多模組程式多模組程式

• 一個多模組程式是一個原始碼已經進入隔開 ASM檔案之內被均分的程式 .

• 每個 ASM檔案 (模組)進入一個隔開的 OBJ 檔案之內被裝配。

• 屬於相同的程式所有的 OBJ 檔案被連接使用連結實效進入一個 EXE 檔案 .

• 這一個程序叫做靜態連接

Page 44: 第  8  章 : 進階程序

Web site Examples 44

優點優點

• 當區分為隔開的原始碼組件,大的程式比較容易寫,保持,而且除錯 .

• 當改變一列編碼的時候,它關閉模組需要在再一次被組合。

• 一個模組可能是合乎邏輯相關的編碼和資料的一個容器(物體-在這裡導向… ) 。• 封裝 : 將模組內的程 序隱藏起來

Page 45: 第  8  章 : 進階程序

Web site Examples 45

產生一個多模組程式產生一個多模組程式

• 當產生一個多模組計畫的時候,這裡是遵從的一些基本步驟:• 產生主要的模組• 為每個程序或相關程序的模組產生一個隔開的原始

碼組件• 產生一包括為外部的程序包含程序原型的檔案(在

模組之間被叫做)• 使用那 INCLUDE 指令使你的程序設計原型可得的

到每個模組

Page 46: 第  8  章 : 進階程序

Web site Examples 46

範例: 範例: ArraySumArraySum 程式 程式

• ArraySum 程式是在第 5 章出現

四個白色的長方形將變成每一個模組 .

Page 47: 第  8  章 : 進階程序

Web site Examples 47

例子程式輸出例子程式輸出

Enter a signed integer: -25

Enter a signed integer: 36

Enter a signed integer: 42

The sum of the integers is: +53

Page 48: 第  8  章 : 進階程序

Web site Examples 48

INCLUDE INCLUDE 檔案檔案

INCLUDE Irvine32.inc

PromptForIntegers PROTO,ptrPrompt:PTR BYTE, ; prompt stringptrArray:PTR DWORD, ; points to the arrayarraySize:DWORD ; size of the array

ArraySum PROTO,ptrArray:PTR DWORD, ; points to the arraycount:DWORD ; size of the array

DisplaySum PROTO,ptrPrompt:PTR BYTE, ; prompt stringtheSum:DWORD ; sum of the array

sum.inc 檔案包含原型外部的功能沒有在 Irvine 32 資料庫中 :

Page 49: 第  8  章 : 進階程序

Web site Examples 49

檢查個別的模組檢查個別的模組

• Main• PromptForIntegers• ArraySum• DisplaySum

訂製一組檔案來集合與連接 .

Page 50: 第  8  章 : 進階程序

Web site Examples 50

The EndThe End