test和cmp一個很菜很基礎的話題!

看雪資料發表於2003-05-19

看過破解教程,都知道test,cmp是比較關鍵,可是我一直不清楚它們究竟是怎麼比較的,最後下決心找了很多資料,和大家一起把它們弄清楚.

首先看看:狀態暫存器(即標誌暫存器)

PSW(Program Flag)程式狀態字(即標誌)暫存器,是一個16位暫存器,由條件碼標誌(flag)和控制標誌構成,
如下所示:

15 14 13 12 11 10 9  8  7  6  5  4  3  2  1  0
        OF DF IF TF SF ZF   AF   PF   CF

條件碼:
①OF(Overflow Flag)溢位標誌,溢位時為1,否則置0.標明一個溢位了的計算,如:結構和目標不匹配.
②SF(Sign Flag)符號標誌,結果為負時置1,否則置0.
③ZF(Zero Flag)零標誌,運算結果為0時置1,否則置0.
④CF(Carry Flag)進位標誌,進位時置1,否則置0.注意:Carry標誌中存放計算後最右的位.
⑤AF(Auxiliary carry Flag)輔助進位標誌,記錄運算時第3位(半個位元組)產生的進位置。
    有進位時1,否則置0.
⑥PF(Parity Flag)奇偶標誌.結果運算元中1的個數為偶數時置1,否則置0.

控制標誌位:
⑦DF(Direction Flag)方向標誌,在串處理指令中控制資訊的方向。
⑧IF(Interrupt Flag)中斷標誌。
⑨TF(Trap Flag)陷井標誌。


為舉例方便說一下jnz和jz
    測試條件
JZ   ZF=1
JNZ  ZF=0
即Jz=jump if zero (結果為0則設定ZF零標誌為1,跳轉)
Jnz=jump if not zero

好,接著來看test和cmp

*******************************************************************************
test屬於邏輯運算指令

功能: 執行BIT與BIT之間的邏輯運算
     測試(兩運算元作與運算,僅修改標誌位,不回送結果).
Test對兩個引數(目標,源)執行AND邏輯操作,並根據結果設定標誌暫存器,結果本身不會儲存。EST AX,BX 與 AND AX,BX 命令有相同效果

語法: TEST r/m,r/m/data
影響標誌: C,O,P,Z,S(其中C與O兩個標誌會被設為0)

運用舉例:
1.Test用來測試一個位,例如暫存器:

test eax, 100b;          b字尾意為二進位制
jnz  ******;             如果eax右數第三個位為1,jnz將會跳轉

我是這樣想的,jnz跳轉的條件是ZF=0,ZF=0意味著ZF(零標誌)沒被置位,即邏輯與結果為1.

2.Test的一個非常普遍的用法是用來測試一方暫存器是否為空:

test ecx, ecx
jz somewhere

如果ecx為零,設定ZF零標誌為1,Jz跳轉

*******************************************************************************
CMP屬於算術運算指令

功能: 比較兩個值(暫存器,記憶體,直接數值)
語法: CMP r/m,r/m/data
標誌位: C,P,A,Z,O

CMP比較.(兩運算元作減法,僅修改標誌位,不回送結果).
cmp實際上是隻設定標誌不儲存結構的減法,並設定Z-flag(零標誌).
零標誌很像carry,也是內部標誌暫存器的一位.

例如:
Cmp eax, 2;       如果eax-2=0即eax=2就設定零標誌為1
Jz ****;          如果設定了零標誌就跳轉


*******************************************************************************
我得出的結論
test邏輯與運算結果為零,就把ZF(零標誌)置1;
cmp 算術減法運算結果為零,就把ZF(零標誌)置1.

結論很簡單嘛,之前我怎麼就分不清呢,真是笨哪!

相關文章