天天看點

彙編語言 CMP指令

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      
彙編語言 CMP指令

以下是目的操作數 = 源操作數的舉例:

; ZF      CF
      mov ax, 1000
      mov cx, 1000
      cmp cx, ax  ;   1       0      
彙編語言 CMP指令

以下是目的操作數 > 源操作數的舉例:

;ZF      CF
mov ax, 105
cmp ax, 0      ;0       0      
彙編語言 CMP指令

使用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指令

使用 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指令
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)