汇编入门学习笔记 (十)—— 标志寄存器、串传送指令 1. ZF标志 2. PF 标志 3. SF标志 4. CF标志 5. OF标志 6. abc 指令 7. sbb指令 8. cmp指令 9. 检測比較结果的条件转移指令 10. DF 标志位和串传送指令 11. pushf和popf

疯狂的暑假学习之  汇编入门学习笔记 (十)——  标志寄存器


參考: 《汇编语言》 王爽 第11章


CPU内部有一种特殊的寄存器叫标志寄存器(flag)。它与ax,bx。cx等其它寄存器不同,它不是用来存放数据的,而是用来存放状态的。

flag寄存器是按位器作用的,即仅仅有0和1。


flag寄存器的结构:

15     14    13    12     11     10     9     8     7     6     5     4     3     2     1     0

                                  OF     DF    IF   SF   ZF                 AF         PF         CF


在debug中标志位的表示:

标志              1               0

of                 OV             NV

sf                 NG             PL

zf                 ZR              NZ

pf                 PE             PO

cf                 CY             NC

df                 DN             UP




零标志位。假设上条相关指令结果为0,那门ZF=1,不为0那门ZF=0

样例:

mov ax,1
sub ax,1


mov ax,1
and ax,0

运行后zf为1


add,sub,mul,div。inc,or,and等这些运算指令会影响标志寄存器

mov,push,pop等转移指令对标志寄存器没有影响


2. PF 标志


奇偶标志位。是0是1的规则 ,类似于奇校验。

假设上条相关指令结果二进制中1的个数为偶数,则PF=1,为奇数则PF=0 。


样例:

mov al,1
add al,10

al = 00001011b

pf = 0


mov al,1
or al,2


al = 00000011b

pf = 1


3. SF标志


符号标志位。

假设上条相关指令结果为负数,则SF=1,正数则SF=0

本质就是看第一位是否为1


mov al,10000001b
add al,1


SF = 1


4. CF标志


表示无符号计算中的进位(注意:inc和dec指令是不影响CF的。但会影响ZF与OF)


样例:

mov al,98H
add al,al

CF = 1


相减为负数,也会使得CF = 1


mov ax,1
sub ax,2


5. OF标志


表示有符号计算的溢出(注意:inc和dec指令是会影响OF的)


比如8位补码 表示的数的范围  -128~127


样例:

mov al,0F0H
add al,88H


-16+(-120) = -136


超过了范围,所以OF = 1



6. abc 指令


带进位的加法指令

abc ax,bx

相当于(ax)=(ax)+(bx)+CF



样例:实现两个128位数据相加


assume cs:code,ds:data

data segment
	db 88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h
	db 11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h
data ends

code segment

start:	mov ax,data
	mov ds,ax
		
	mov si,0
	mov di,16
		
	mov cx,8
		
	call add128
		
add128:	push ax
	push cx
	push si
	push di
		
	sub ax,ax    ;将CF设置为0
s:	mov ax,[si]
	adc ax,[di]
	mov [si],ax
	inc si      ;不用add是由于add会改变CF的值
	inc si
	inc di
	inc di
	loop s
		
	pop di
	pop si
	pop cx
	pop ax
		
		

code ends

end start


7. sbb指令


sbb是带借位的减法指令

sbb ax,bx 相当于(ax)=(ax)-(bx)-CF


8. cmp指令


cmp是比較指令。相当于减法,但不保存结果仅仅改变flag


cmp ax。bx

对于无符号数来说

假设(ax)=(bx)     则(ax)-(bx)=0。   所以:zf = 1;

假设(ax)!=(bx)  则(ax)-(bx)!

=0,所以:zf = 0。

假设(ax)< (bx)    则(ax)-(bx)会产生错位。所以:cf = 1;

假设(ax)>(bx)   则(ax)-(bx)不会产生错位,结果也不可能为0, 所以:cf = 0 而且zf = 0。

能够这么说:

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,     说明 (ax)<=(bx)


对于有符号数来说

zf = 1  说明 (ax)=(bx)

zf = 0  说明 (ax)!=(bx)

sf=1 而且 of=0,说明(ax)<(bx)

sf=0 而且 of=1,说明(ax)<(bx)

sf=1 而且 of=1,说明(ax)>(bx)

sf=0 而且 of=0。说明(ax)>=(bx)



9. 检測比較结果的条件转移指令



对于无符号数:


je          等于则转移         zf=1

jne        不等于则转移      zf=0

jb          低于则转移         cf=1

jnb        不低于则转移      cf=0

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

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


各个字母的意思:

j:jmp

e:equal

ne:not equal

b:below

nb:not below

a:above

na:not above


比如实现:假设(ah)=(bh)则(ah)=(ah)+(ah),否则(ah)=(ah)+(bh)

    cmp ah,bh
    je s
    add ah,bh
s: add ah,ah


样例:计算data段中为8的数的个数,记录在ax中

assume cs:code,ds:data

data segment
	db 8,11,23,8,2,3,8,8
data ends

code segment

start:	mov ax,data
	mov ds,ax
		
	mov si,0
	mov ax,0
	mov cx,8
s:	cmp byte ptr ds:[si],8
	jne next
	inc ax
next:	inc si
	loop s
		
	mov ax,4c00H
	int 21H
		
	
code ends

end start


10. DF 标志位和串传送指令



df=0  每次操作后si、di递增;

df=1 每次操作后si、di递减;


movsb

功能:将ds:si 指向的内存单元中的字节送入es:di中。然后依据标志寄存器df位的值。将si和di递增或递减1

相当于:

(1)((es)*16+(di))=((ds)*16+(si)

(2)df=0则:(si)=(si)+1

                       (di)=(di)+1

         df=1则:(si)=(si)-1

                       (di)=(di)-1


movsw

功能:于movsb同样,仅仅是是传送一个字,然后就是si和di是递增或递减2




指令cld。std

cld:将df设置为0

std:将df设置为1


rep指令

功能:依据cx的值反复运行。后面的串指令。

格式:rep movsb



样例:复制data中的'Welcome to masm!'

assume cs:code,ds:data

data segment
	db 'Welcome to masm!'
	db 16 dup(0)
data ends

code segment

start:	mov ax,data
	mov ds,ax
		
	mov es,ax
	mov di,16
	mov si,0
	mov cx,16
	cld
	rep movsb
		
	mov ax,4c00h
	int 21h
		
code ends

end start


11. pushf和popf


pushf的功能是将标志寄存器的值压栈。而popf是从栈中弹出数据。送入标志寄存器中