在8086CPU中有一個特殊的寄存器——標志寄存器,該寄存器不同於其他寄存器,普通寄存器是用來存放數據的讀取整個寄存器具有一定的含義,但是標志寄存器是每一位都有固定的含義,記錄在運算中產生的信息,標志寄存器的機構如下圖:

寄存器中的第1、3、5、 12、 13、 14 、15位在8086CPU中沒有使用,其他位置代表不同的含義,各個位置的意思如下(該表截自百度知百科中的標志寄存器):

一般我們常用到的是如下幾個標志
1)CF:CF標志表示進位,我們知道對於8086CPU來說,寄存器只能存儲16位二進制數,但是有些指令產生的結果可能大於16位,比如:
mov ax,200h add ax, 0fffffh產生的結果已經超過16位,由於ax寄存器只能保存16位數據,因此高位產生的數據必然被丟棄,但是也不是簡單的丟棄,這個時候CF標志位會變成1,表示結果產生了進位;
2)PF:表示標志,這個奇偶不是數字本身是奇數或者是偶數,表示的是某個數據中有奇數個1或者是偶數個1;
3)ZF:0標志:表示計算結果是否為0;
4)SF:符號標志記錄相關計算結束后得到的結果是否為負,若為負則標志位為1,否則標志位為0;
5)方向標志:方向標志用於內存單元的拷貝,我們在將一段內存單元拷貝到另一段內存中去時使用循環一個字節一個字節的拷貝,但是8086CPU提供了一個指令movsb 、movsw分別是按字節拷貝和按字拷貝,這兩個指令所對應的源內存地址只能用
ds:[si],目的地址只能用es:[di]表示,其中DF標志指明我們是從低到高字節拷貝還是從高到低字節拷貝,當df = 1時,地址遞減, = 0時地址遞增;
6)OF:溢出標志,它的作用與CF相同,當得到的操作數大於16位的時候,該標志置為1,但是OF用於有符號數,而CF用於無符號數。
7)IF:在DEBUG中使用,當我們啟動DEBUG模式的時候,一條指令執行完后,該寄存器被置為1,這個時候會調用相應的中斷程序,使我們的代碼在該位置停止執行,以便我們查看相應的結果;
CMP指令
CNP指令使用的格式為CMP 操作數1,操作數2;
cmp指令的作用是將兩個操作數相減,並根據結果改變標志寄存器的值,但是並不保存計算結果,當兩個數都為正時,如果ZF = 0則說明兩個數相等,這個指令一般用於判斷兩個數據的大小關系,如果我們只是使用它,那么在判斷兩個數字的大小關系上,可能還會判斷其他內容,假設我們使用了cmp n1, n2這樣的指令的話,那么可能出現三種情況:
1)n1 = n2:要判斷是不是出現這種情況只需要判斷ZF是否為0,當ZF為0時兩數相等;
2)n1 >n2:我們知道大數減去小數結果一定為正,是不是只需要判斷SF呢?不是!在數學上大數減去小數結果一定為正這是肯定的,但是在計算機中確並不一定是這樣的,我們需要考慮到是否溢出的問題比如“ffffh - (-2)”這個結果在數學上肯定是負數,但是在計算機上結果卻為正,,這個時候除了要校驗SF還需要校驗OF,當溢出產生的時候結果正好與我們使用SF校驗的相反;
3)n1 < n2:這個結果的校驗與上述的校驗類似;
然而幸運的是,在我們實際比較兩個數據大小的時候我們並不需要這樣,80886CPU為我們提供了一系列指令用來做這個工作:
指令 含義 檢測的相關標志位
je:(jmp equal) 當兩數相等時跳轉;ZF = 1
jne(jmp not equal): 當兩數不相等的時候跳轉;ZF = 0
jb(jmp blow); 小於時跳轉;CF = 1
jnb(jmp not blow) 不小於時跳轉;CF = 0
ja(jmp above) 大於時跳轉;CF= 0且ZF = 0
jna(jmp not above) 不大於時跳轉;CF = 1或ZF = 0
以上指令指示檢測標志寄存器中相應位置的值來判斷,至於在它的前面是否使用了cmp指令CPU並不關心,在執行這些指令的時候只要CPU檢測到相關的標志滿足條件則會自動跳轉,比如執行下面的指令:
mov ax,0 add ax,ax je s1 inc ax s1: inc ax
CPU執行到je的時候檢測到ZF寄存器為0,這個時候會自動跳轉到s1處的代碼中執行,不會執行je的下一行代碼。為了實現比較功能最好將cmp與這些指令配套使用。高級語言中的if語句正是用着一套指令實現的
一般在破解時可能需要修改某些標識,以達到跳轉或者不跳轉的目的,下面是我從小甲魚網站上找到的圖片,記錄了各個跳轉指令實現所需要的條件,根據這個表中的內容,修改相應標識,就可以控制程序執行流程

