13-ZF標誌位,JB和JNB跳轉指令
1. ZF標誌位
這一節我們將來學習一下標誌暫存器的ZF(Zero Flag)零標誌位。
對於ZF標誌位,當運算結果為0的時候,那麼ZF=1,當運算結果不為0的時候,ZF=0。
例如下面這段彙編指令:
mov ax,10
mov dx,10
sub ax,dx
但sub指令一旦執行,就會修改暫存器裡面的值,當ax和dx進行減法運算的結果為0時,那麼ZF標誌位就會被置為1。有些時候,我們需要判斷一些兩個數相減是不是等於0,可我們又不希望影響了暫存器裡面的值,這個時候,我們可以使用cmp指令代替sub指令。
cmp指令(compare),cmp指令用法如下:
cmp ax,dx
cmp和sub都是進行減法運算,但cmp隻影響標誌暫存器;而sub不僅會影響標誌暫存器,還會影響被減數所在的暫存器或者記憶體。因此,當需要判斷兩個數字是不是相等,就可以使用cmp指令。
當然我們也可以使用cmp指令判斷被加數是不是大於加數,只需要觀察CF標誌位就可以了。
2. JB和JNB
JB指令(英文:jump when below)可以簡單理解為是一個跳轉指令,當CF標誌位為1的時候才會跳轉。
而JNAE指令(英文:jump when not above or equal)和JB指令所做的事情幾乎是一模一樣的,也就是說你既可以使用JB指令,也可以使用JNAE指令。
JNB指令(英文:jump when not below)也是用於跳轉的,不過JNB指令只在CF標誌位為0的時候才跳轉,JAE指令(英文:jump when above or equal)和JNB指令是完成一模一樣的事情。
單獨使用JB和JNB指令並沒有太大的意義,通常都是和cmp指令一起使用,它們一組合,就會產生化腐朽為神奇的效果。我們知道CMP運算之後會影響CF的值,然後JB或者JNB指令會根據CF決定跳轉程式碼。
有了這些指令,就可以讓我們的程式具有一定的“智慧和思考”。比如設計一個程式功能:輸入一個年齡,如果這個年齡是18歲以上(包括18)歲,就在螢幕上顯示“Adult”,如果這個年齡小於18歲,在螢幕上顯示“Minor”
彙編程式碼如下:
;檔案說明:005.asm
;說明:JB指令使用
mov ax,0xB800
mov es,ax ;指定顯示段
mov ax,0x07c0
mov ds,ax ;指定資料段
mov si,0 ;初始化資料段 偏移暫存器(源地址)
mov di,0 ;初始化顯示段 偏移暫存器(目的地址)
jmp near code
Age:
db 16 ;指定年齡,你也可以自行指定年齡數
Adult:
db 'Adult'
Minor:
db 'Minor'
code:
mov al,byte[ds:Age]
cmp al,18 ;如果比18小,根據CF標誌位變化,使用JB指令跳轉到指定位置
JB PrintMinor
PrintAdult: ;列印成年
mov cx,Minor-Adult ;確定要列印的位元組數
mov si,Adult
jmp PrintLoop
PrintMinor: ;列印未成年
mov cx,code-Minor ;確定要列印的位元組數
mov si,Minor
PrintLoop:
mov al,[ds:si]
mov byte [es:di],al
inc di
mov byte [es:di],0x07
inc si
inc di
loop PrintLoop
end:
jmp 0x07C0:end
times 510-($-$$) db 0x00
db 0x55,0xAA
指定年齡為16,執行結果如下:
指定年齡為20,執行結果如下:
JE指令和JZ指令:
JE指令和JZ指令所做的事情都是一樣的,用於跳轉的,即當ZF標誌位為1時就會跳轉。JNE指令和JNZ指令則是當ZF標誌位為0時才會跳轉。無論是JE指令還是JNE指令,通常都是和CMP指令一起使用的,其用法和JB指令,JNB指令是類似的。