一. cmp 指令
1. cmp 指令功能
cmp (compare) 是比较指令,cmp 的功能相当于减法指令,只是不保存结果,但会根据结果对标志寄存器进行设置,其它相关指令就可以通过识别这些被影响的标志寄存器的位来得知比较结果。
2. cmp指令格式
cmp 操作对象1, 操作对象2。
3. cmp 指令的 CPU 工作原理
对于指令:cmp ax, bx
CPU 执行该指令,会计算 (ax) - (bx) ,然后根据结果对 CPU 的标志寄存器进行设置,那么,我们可以做以下分析:
- 1. 如果 ax = bx,那么 ax - bx = 0,所以,ZF = 1
- 2. 如果 ax != bx,那么 ax - bx != 0,所以,ZF = 0
- 3. 如果 ax < bx,那么 ax - bx < 0,ax 的最高有效位将向假想的更高位借位,所以,CF = 1
- 4. 如果 ax >= bx,那么 ax - bx >= 0,不用借位,所以,CF = 0
- 5. 如果 ax > bx,那么 ax - bx > 0,所以,ZF = 0,不用借位,所以,CF = 0
- 6. 如果 ax <= bx,那么 ax - bx <= 0,这时可能结果为 0 或可能要借位,所以 ZF = 1 或 CF = 1
tips:
关于标志寄存器相关位表示的含义,可以看链接里博文的介绍汇编语言:标志寄存器ZF、PF、SF、CF、OF、DF、IF、AF_汇编pf标志位-CSDN博客
那么对于CPU来说,执行 cmp ax bx 指令后,CPU 就可以通过标志寄存器对应位的值,从而知道比较 ax,bx 的大小的结果。
- 1. 如果 ZF = 1,那么 ax = bx
- 2. 如果 ZF = 0,那么 ax != bx
- 3. 如果 CF = 1,那么 ax < bx
- 4. 如果 CF = 0,那么 ax >= bx
- 5. 如果 CF = 0 && ZF = 0,那么 ax > bx
- 6. 如果 ZF = 1 || CF = 1,那么 ax <= bx
二. je 指令
je(jump equal),等于则转移,检测的相关的标志:ZF = 1。
指令格式:je 标号
示例:
je s ;等于则跳转到 s 标号处执行指令,CPU实际是检测 ZF = 1
assume cs:code, ds:data
data segment
db 'ax = bx',0
db 'ax != bx',0
data ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, 3 ;ax = 3
mov bx, 3 ;bx = 3
cmp ax, bx ;计算 ax - bx,并根据结果设置标志寄存器
je ax_e_bx ;等于则跳转,CPU实际是检测 ZF = 1
mov cl, 4 ;红色
call size_str ;计算第一个显示的字符串占用的字节数,结果放在 ax 中
mov si, ax ;si = ax,指向第二个字符串的首地址
jmp short ok ;jmp短转移指令,相当于当前 IP,能转移的范围在:-128 ~ 127,即:IP - 128 ~ IP + 127 这个偏移地址
ax_e_bx:
mov cl, 2 ;绿色
mov si, 0 ;指向第一个字符串的首地址
ok:
mov dh, 14 ;14行
mov dl, 32 ;32列
call show_str ;显示字符串
mov ax, 4c00h
int 21h
;名称:size_str
;功能:求一个以0结尾的字符串的字节数
;参数:ds:si指向字符串的首地址
;返回:求的字符串长度存储在 ax 中
size_str:
push cx
mov ch, 0
mov ax, 1
loop_size_str:
mov cl, ds:[si]
jcxz ok_size_str
inc ax
inc si
loop loop_size_str
ok_size_str:
pop cx
ret
;名称:show_str
;功能:在指定的位置,用指定的颜色,显示一个以0结尾的字符串
;参数:dh=行号(取值范围:0-24),dl=列号(取值范围:0-79)
; cl=颜色,ds:si指向字符串的首地址
;返回值:无
show_str:
;B8000h-BFFFFh共32kb,是80 * 25彩色字符模式的显示缓冲区,每页4kb(4000字节),显示器可以显示任意一页的内容。
;一般情况下,显示第0页的内容, 也就是说,B8000h ~ B8F9Fh 这4000个字节的内容会显示在显示器上。每行80个字,
;每个字占2个字节,低字节存放字符的assii码,高字节为属性字节。所以每行占160个字节
mov ax, 0B800h ;显示缓冲区段