Loop
用ECX作為counter,下面的範例code會loop 5次
mov ecx, 5
L:
; do something
loop L
FLAGS
ALU中有這些FLAG,反映算術運算後的結果
- Sign Flag: 當結果變成負數
- Carry Flag: 當unsigned numbers超出範圍
- Zero Flag: 當結果變成0
- Overflow Flag: 當signed numbers超出範圍
ESI(Source Index)
[esi] : dereference該位址的值
mov al, [esi] ; [esi] dereference the value of the address of esi
OFFSET
回傳一個指標
.data
array BYTE 1000 DUP(?)
.code
mov esi, OFFSET array
STACK
Stack在記憶體中的位置。其中你寫的程式碼、在程式碼中.data部分宣告的變數也會被存在記憶體如下圖的相對位置中。
從上圖也可以發現,在stack越上面的元素,他的位址就越小。
基本stack操作
push及pop的大小由暫存器、記憶體決定,但只能是4 byte或是2 byte
push eax
pop eax
ESP (Stack pointer)
指向stack中的最上面的元素的一個暫存器。
巢狀迴圈
stack一個很常見的用途就是巢狀迴圈。
外層迴圈要進入內層迴圈時,先把外層迴圈counter(ECX)的值push進stack中,等到離開內層迴圈後再將外層迴圈counter(ECX)的值pop出來。
mov ecx, 5
L1:
; do something
push ecx
mov ecx 10
L2:
; do something else
loop L2
pop ecx
loop L1
Procedures
有點類似高階語言的function
怎麼寫一個Procedure
[function名稱] PROC
; something you want procedures to do
[function名稱] ENDP
CALL
呼叫你的Procedure,把call XX那行接下來要執行的指令的位址先push到stack,ESP就會指向那個位址。再把EIP指向XX Procedure的第一行
RET
把stack最上面的元素pop給EIP。其實就等於pop EIP。
USES
在進入procedure前保存指定的暫存器的值,結束後再回復到進入procedure前的值。
算是個語法糖。剛進到procedure的時候先push到stack,離開時再從stack中pop出來。
Sample PROC USES EAX
; do something in procedure
Sample ENDP