CMP(比較)指令執行從目的操作數中減去源操作數的隐含減法操作,并且不修改任何操作數。
指令格式:
CMP 目的操作數, 源操作數
标志位 當實際的減法發生時,CMP指令按照計算結果修改溢出、符号、零、進位、輔助進位和奇偶标志位。如果比較的是兩個無符号數,則零标志位和進位标志位表示的兩個操作數之間的關系如下表所示:
CMP結果 | ZF | CF |
目的操作數 < 源操作數 | 1 | |
目的操作數 > 源操作數 | ||
目的操作數 = 源操作數 | 1 |
如果比較的是兩個有符号數,則符号标志位、零标志位和溢出标志位表示的兩個操作數之間的關系如下表所示:
CMP結果 | 标志位 |
目的操作數 < 源操作數 | SF ≠ OF |
目的操作數 > 源操作數 | SF = OF |
目的操作數 = 源操作數 | ZF = 1 |
CMP指令是建立條件邏輯結構的重要工具。當在條件跳轉指令中使用CMP時,彙編語言的執行結果就和IF語句一樣。
以下是目的操作數 < 源操作數的舉例:
; ZF CF
mov ax, 5
cmp ax, 10 ; 0 1
以下是目的操作數 = 源操作數的舉例:
; ZF CF
mov ax, 1000
mov cx, 1000
cmp cx, ax ; 1 0
以下是目的操作數 > 源操作數的舉例:
;ZF CF
mov ax, 105
cmp ax, 0 ;0 0
使用CMP指令統計data 段中數值為8的位元組個數,用ax儲存統計結果。
; 1.程式設計 統計data 段中數值為8的位元組個數,用ax儲存統計結果
assume cs:code, ds:data, ss:stack
data segment
db 8, 11, 8, 1, 8, 5, 63, 38
data ends
stack segment stack
db 128 dup(0)
stack ends
code segment
start: mov ax, stack
mov ss,ax
mov sp, 128
call init_reg
call get_eight
mov ax, 4C00H
int 21H
;============================================
get_eight:
mov si,0
mov cx, 8
mov ax, 0
getEight: cmp byte ptr ds:[si], 8
jne nextNumber
inc ax
nextNumber: inc si
loop getEight
ret
;===============================================
init_reg:
mov bx, data
mov ds, bx
ret
code ends
end start
使用 CMP指令 統計data 段中數值大于8的位元組個數,用ax儲存統計結果
; 2.程式設計 統計data 段中數值大于8的位元組個數,用ax儲存統計結果
assume cs:code, ds:data, ss:stack
data segment
db 8, 11, 8, 12, 8, 5, 63, 38
data ends
stack segment stack
db 128 dup(0)
stack ends
code segment
start: mov ax, stack
mov ss,ax
mov sp, 128
call init_reg
call get_eight
mov ax, 4C00H
int 21H
;============================================
get_eight:
mov si,0
mov cx, 8
mov ax, 0
getEight: cmp byte ptr ds:[si], 8
jna nextNumber ; ja > na <=
inc ax
nextNumber: inc si
loop getEight
ret
;===============================================
init_reg:
mov bx, data
mov ds, bx
ret
code ends
end start
CMP ax, bx | 修改标志位 | 符号描述 |
ax = bx | ZF = 1 | 相等 |
ax != bx | ZF = 0 | 不相等 |
ax < bx | CF = 1 | 小于 |
ax >= bx | CF = 0 | 大于等于 |
ax > bx | CF = 0 并且 ZF = 0 | 大于 |
ax <= bx | CF = 1 或者 ZF = 1 | 小于等于 |
基于有符号的舉例:
mov al, 1
mov bl, 2
cmp al, bl → 推理出來 al < bl
sub al, bl → 影響标志位 1 - 2 = -1 SF 符号标志位置1
mov al, 22H → 34 34 - (-96) = 140 -128 ~ 127
mov bl, A0H -96
sub al, bl → OF标志位 和 SF标志位 溢出标志位置1 符号标志位置1
mov al, 8AH -118 - 112 = - 230 溢出 1A 正數
mov bl, 70H
cmp al, bl OF = 1 SF = 0 溢出标志位置1 符号标志位置0
總結:基于有符号比較
設 cmp al, bl
如果 SF = 1 OF = 0
那麼 al < bl
如果SF = 1 OF =1
那麼 al > bl
如果 SF = 0 OF = 1
因為 SF = 0
不等式應該為 al - bl > 0 al > bl
當OF = 1 成立時,那麼
al < bl
如果SF = 0 OF = 0
那麼 al - bl > 0
得到 al > bl
如果因為溢出導緻了實際結果為負,那麼邏輯上真正的結果必然為正。
如果因為溢出導緻了實際結果為正,那麼邏輯上真正的結果必然為負。
基于無符号數比較的跳轉
助記符 | 說明 |
JB | 小于跳轉 |
JNB | 不小于跳轉 |
JNBE | 不小于或等于跳轉 |
JA | 大于跳轉 |
JNA | 不大于跳轉 |
JNAE | 不大于或等于跳轉 |
基于相等性的跳轉
助記符 | 說明 |
JE | 相等跳轉 |
JNE | 不相等跳轉 |
JCXZ | CX = 0 跳轉 |
JECXZ | ECX = 0 跳轉 |
JRCXZ | RCX = 0 跳轉(64模式) |
基于有符号數比較的跳轉
助記符 | 說明 |
JG | 大于跳轉 |
JL | 小于跳轉 |
JNLE | 不小于或等于跳轉 |
JNGE | 不大于活等于跳轉 |
JGE | 大于或等于跳轉 |
JLE | 小于或等于跳轉 |
JNL | 不小于跳轉 |
JNG | 不大于跳轉 |
基于進位和零标志位的跳轉
助記符 | 說明 |
JC | 進位跳轉(進位标志位置1) |
JNC | 無進位跳轉(進位标志位清零) |
JZ | 為零跳轉(零标志位置1) |