mthoutai

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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


參考: 《汇编语言》 王爽 第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



1. ZF标志


零标志位。假设上条相关指令结果为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是从栈中弹出数据。送入标志寄存器中



posted on 2017-07-04 19:32  mthoutai  阅读(780)  评论(0编辑  收藏  举报