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