汇编入门学习笔记 (十)—— 标志寄存器、串传送指令

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


参考: 《汇编语言》 王爽 第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是从栈中弹出数据,送入标志寄存器中



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值