Skip to content
This repository has been archived by the owner on May 9, 2023. It is now read-only.

Latest commit

 

History

History
408 lines (249 loc) · 7.35 KB

26.md

File metadata and controls

408 lines (249 loc) · 7.35 KB

第26节 CMP比较指令和条件转移指令

❤️💕💕汇编语言目前仍在发挥着不可替代的作用,在效率上无可替代,在底层,学习linux内核,计算机外围设备和驱动,都离不开汇编。Myblog:http://nsddd.top


[TOC]

CMP 指令(比较指令)

cmp是比较指令,cmp的功能相当于减法指令,只是不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。

cmp 指令格式

cmp 操作对象1, 操作对象2

功能

操作对象1 - 操作对象2

计算操作对象1 - 操作对象2但并不保存结果,仅仅根据计算结果对标志寄存器进行设置。

比如

cmp ax, ax

指令做(ax)-(ax)的运算,结果为0,但并不再ax中保存,仅影响flag的相关各位。指令执行后:zf = 1,pf = 1, sf = 0,cf = 0,of = 0。

无符号数比较:

下面的指令:

mov ax, 8
mov bx, 3
cmp ax, bx

执行后:(ax)= 8,zf = 0,(pf)= 1,sf = 0, cf = 0, of = 0。

无符号数比较和标志位取值

cmp ax, bx 

如果(ax=bx)则(ax-bx= 0,所以:zf = 1;

如果(ax!=bx)则 (ax-bx!= 0,所以:zf != 1;

如果(ax<bx)则(ax-bx)将产生借位,所以:cf = 1;

如果(ax>=bx)则(ax-bx)将不会产生借位,所以:cf = 0;

如果(ax>bx)则(ax-bx)即不借位,结果又不为零,所以:cf = 0zf = 0; 

如果(ax<=bx)则(ax-bx)即可能借位,结果可能为0,所以:cf = 1zf = 1

通过做减法运算,影响标志寄存器,标志寄存器的相关位记录了比较的结果。

zf = 1,说明(ax=bxzf = 0,说明(ax!=bxcf = 1,说明(ax<bxcf = 0,说明(ax>=bxcf = 0 并且 zf = 0,说明(ax>bxcf = 1zf = 1,说明(ax<=bx

有符号数比较:

cmp ah, bh

如果(ah)=(bh)则(ah)-(bh)= 0,所以 zf = 1;

如果(ah)!=(bh)则(ah)-(bh)!= 0,所以 zf = 0;

根据cmp指令执行后zf的值,就可以知道两个数据是否相等。

当结果发生了溢出cmp指令单纯的关注sf的值是不能得出正确的正负结果的。

1)如果 sf = 1,而 of = 0

of = 0,说明没有溢出,逻辑上真正结果的正负 = 实际结果的正负。

sf = 1,实际结果为负,所以逻辑上真正的结果为负,所以(ah)<(bh)。

2)如果 sf = 1,而 of = 1

of = 1,说明有溢出,逻辑上真正结果的正负 != 实际结果的正负。

因sf = 1,实际结果为负。

如果因为溢出导致实际结果为负,那么逻辑上真正的结果必然为正。

sf = 1,of = 1,说明了(ah)>(bh)。

3)如果 sf = 0,而 of = 1

of = 1,说明有溢出,逻辑上真正结果的正负 != 实际结果的正负。

sf = 0,说明实际结果为正。

如果因为溢出导致实际结果为正,那么逻辑上真正的结果必然为负。

sf = 0,of = 1,说明了(ah)<(bh)

4)如果 sf = 0,of = 0

of = 0,说明没有溢出,逻辑上真正结果的正负 = 实际结果的正负。

sf = 0,实际结果为正,所以逻辑上真正的结果为正,所以(ah)>(bh)。

检测比较结果的条件转移指令

“转移”指的是它能够修改IP,而“条件”指的是它可以根据某种条件,决定是否修改IP。

这些条件转移指令通常都和cmp相配合使用。

因为cmp指令可以同时进行两种比较,无符号数和有符号数比较,所以根据cmp指令的比较结果进行转移的指令也分为两种:

 1)根据无符号数的比较结果进行转移的条件转移指令(检测zf、cf的值)

 2)根据有符号数的比较结果进行转移的条件转移指令(检测zf、cf 和 of 的值)

无符号转移指令

指令              含义                  检测的相关标志位     

je               等于则转移               zf = 1

jne              不等于则转移             zf = 0

jb               低于则转移               cf = 1

jnb              不低于则转移             cf = 0

ja               高于则转移               zf = 0 且 zf = 0

jna              不高于则转移             zf = 1 或 cf = 1

:实现(ah)=(bh)则(ah)=(ah)+(ah),否则(ah)=(ah)+(bh)

	 cmp ahbh
	 je s	;zf == 1 转移
	 add ah, bh
	 jmp short ok	

  s: add ah, ah

 ok:     :
         :

je检测的是zf位置,不管je前面是什么指令,只要CPU执行je指令时,zf = 1,那么就会发生转移。

	mov ax, 0
	add ax, 0
	
	je s
	
	inc ax
	
 s: inc ax

:统计data段中数值为8的字节的个数,用ax保存统计结果

assume cs:code, ds:data

data segment 

	db 8, 11, 8, 1, 8, 5, 63, 38

data ends


code segment

	start:  mov ax, data
			mov ds, ax
			mov ax, 0
			mov cx, 8
			mov bx, 0
		
		s:  map pyte bty ds:[bx], 8
			jne s0
			inc ax

	   s0:  inc bx
			loop s
						
			mov ax, 4C00H
			int 21H		

code ends

end start

assume cs:code, ds:data

data segment 

	db 8, 11, 8, 1, 8, 5, 63, 38

data ends


code segment

	start:  mov ax, data
			mov ds, ax
			mov ax, 0
			mov cx, 8
			mov bx, 0
		
		s:  map pyte bty ds:[bx], 8
			je s0
			jmp short next

	   s0:  inc ax

	 next:	inc bx
			loop s
						
			mov ax, 4C00H
			int 21H		

code ends

end start

:计算data段中数值大于8的字节的个数,用ax保存统计结果。

assume cs:code, ds:data

data segment 

	db 8, 11, 8, 1, 8, 5, 63, 38

data ends


code segment

	start:  mov ax, data
			mov ds, ax
			mov ax, 0
			mov cx, 8
			mov bx, 0
		
		s:  map pyte bty ds:[bx], 8
			jna s0
			inc ax

	   s0:  inc bx
			loop s
						
			mov ax, 4C00H
			int 21H		

code ends

end start

:计算data段中数值小于8的字节的个数,用ax保存统计结果。

assume cs:code, ds:data

data segment 

	db 8, 11, 8, 1, 8, 5, 63, 38

data ends


code segment

	start:  mov ax, data
			mov ds, ax
			mov ax, 0
			mov cx, 8
			mov bx, 0
		
		s:  map pyte bty ds:[bx], 8
			jnb s0
			inc ax

	   s0:  inc bx
			loop s
						
			mov ax, 4C00H
			int 21H		

code ends

end start

:统计F000:0处32个字节中,大小在[32,128]的数据的个数。

	mov ax, of000
	mov ds, ax
	
	mov bx, 0
	mov dx, 0
	mov cx, 32

s:  mov al, ds:[bx]

	cmp al, 32
	jb s0
	
	cmp al, 128
	ja s0

	inc dx

s0: inc bx
	loop s

:统计F000:0处32个字节中,大小在(32,128)的数据的个数。

	mov ax, of000
	mov ds, ax
	
	mov bx, 0
	mov dx, 0
	mov cx, 32

s:  mov al, ds:[bx]

	cmp al, 32
	jna s0
	
	cmp al, 128
	jnb s0

	inc dx

s0: inc bx
	loop s

END 链接