张狂的暑假学习之 汇编入门学习笔记 (十)—— 标志寄存器
参阅: 《汇编语言》 王爽 第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
比如:
- movax,1
- subax,1
- movax,1
- andax,0
履行后zf为1
add,sub,mul,div,inc,or,and等这些运算指令会影响标志寄存器
mov,push,pop等搬运指令对标志寄存器没有影响
2. PF 标志
奇偶标志位。是0是1的规矩 ,类似于奇校验。
假如上条相关指令成果二进制中1的个数为偶数,则PF=1,为奇数则PF=0 。
比如:
- moval,1
- addal,10
al = 00001011b
pf = 0
- moval,1
- oral,2
al = 00000011b
pf = 1
3. SF标志
符号标志位。
假如上条相关指令成果为负数,则SF=1,正数则SF=0
实质便是看第一位是否为1
- moval,10000001b
- addal,1
SF = 1
4. CF标志
表明无符号核算中的进位(留意:inc和dec指令是不影响CF的,但会影响ZF与OF)
比如:
- moval,98H
- addal,al
CF = 1
相减为负数,也会使得CF = 1
- movax,1
- subax,2
5. OF标志
表明有符号核算的溢出(留意:inc和dec指令是会影响OF的)
例如8位补码 表明的数的规模 -128~127
比如:
- moval,0F0H
- addal,88H
-16+(-120) = -136
超过了规模,所以OF = 1
6. abc 指令
带进位的加法指令
abc ax,bx
相当于(ax)=(ax)+(bx)+CF
比如:完成两个128位数据相加
- assumecs:code,ds:data
- datasegment
- db88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h,88h
- db11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h,11h
- dataends
- codesegment
- start:movax,data
- movds,ax
- movsi,0
- movdi,16
- movcx,8
- calladd128
- add128:pushax
- pushcx
- pushsi
- pushdi
- subax,ax;将CF设置为0
- s:movax,[si]
- adcax,[di]
- mov[si],ax
- incsi;不必add是因为add会改动CF的值
- incsi
- incdi
- incdi
- loops
- popdi
- popsi
- popcx
- popax
- codeends
- endstart
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)
- cmpah,bh
- jes
- addah,bh
- ddah,ah
比如:核算data段中为8的数的个数,记录在ax中
- assumecs:code,ds:data
- datasegment
- db8,11,23,8,2,3,8,8
- dataends
- codesegment
- start:movax,data
- movds,ax
- movsi,0
- movax,0
- movcx,8
- s:cmpbyteptrds:[si],8
- jnenext
- incax
- next:incsi
- loops
- movax,4c00H
- int21H
- codeends
- endstart
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!
- assumecs:code,ds:data
- datasegment
- dbWelcometomasm!
- db16dup(0)
- dataends
- codesegment
- start:movax,data
- movds,ax
- moves,ax
- movdi,16
- movsi,0
- movcx,16
- cld
- repmovsb
- movax,4c00h
- int21h
- codeends
- endstart
11. pushf和popf
pushf的功用是将标志寄存器的值压栈,而popf是从栈中弹出数据,送入标志寄存器中