ZF标志
ZF标志是零标志位(zero flag);她记录相关指令执行后,其结果是否为0,如果为0,则ZF = 1,如果不为0 ,则 ZF = 0
例如
mov ax,1
sub ax,1
上面指令执行后,ZF= 1
PF标志
PF标志是奇偶标志位(parity flag),他记录相关指令执行后,其结果所有的bit位中1的个数是否为偶数,如果为偶数,则PF= 1,否则为0
mov al,1
add al,10 ;11 = 1011B
上面执行后结果是11,有3个1,所以PF = 0
SF 标志
SF是符号标志位(sign flag),用于记录相关结果是否为负数,如果结果为负数,SF= 1,如果非负数,则SF= 0
CF标志
CF标志是进位标志(carry flag),一般情况下,在进行无符号运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位借位值
mov al,98h
add al,al ;执行后,(al) = 30h,CF = 1,C记录了从最高位有效位向更高位的进位值
add al,al;执行后,(al) = 60h,CF = 0,C记录了从最高位有效位向更高位的进位值
OF标志
OF标志是溢出标志(overflow flag),OF记录了有符号数运算的结果是否产生溢出,如果发生溢出,OF=1,如果没有 OF=0
mov al,98
add al,99
执行add命令后,CF=0,OF=1;CPU在执行add等指令的时候,就包含了两种含义,无符号数运算和有符号数运算,对于无符号数运算,CPU用CF位来记录是否产生了进位,对于有符号数运算,CPU用OF位记录是否产生了溢出,对于无符号数运算,98+99没有进位,CF=0;对于有符号数运算,98+99产生溢出,OF=0
abc指令
说了这么多的标志,现在看看这些标志如何使用的
adc 操作对象1,操作对象2
功能:操作对象1 = 操作对象1 +操作对象2 + CF
mov ax,2
mov bx,1
sub bx,ax;这里需要向高位借1
abc ax,1
上面执行结束后 (ax) = 4,这是因为 (ax) = (ax)+1+(CF) = 2+1+1 = 4
mov ax,1
add ,ax,ax
abc ax,1 ; ax = 2+ 1+ 0= 3
为什么会出现abc指令,现在需要计算0198H和0183H的和
实际上面加法可以看作两步进行1)低位相加 2)高位相加在相加地位产生的进位数
add al,bl
abc ah,bh
sbb指令
sbb是带有借位减法指令,他利用了记录的借位值
sbb sbb操作对象1,操作对象2
功能:操作对象1 = 操作对象1 -操作对象2 -CF
计算003E1000H - 00202000H
mov bx,1000H
mov ax,003EH
sub bx,2000H
sbb ax,0020H
cmp指令
cmp是比较指令,cmp功能相当于减法指令,知识不保存结果,但是对寄存器产生影响。
格式:cmp 操作对象1,操作对象2
功能:计算操作对象1- 操作对象2,但是不保存结果,仅仅根据计算结果对标志寄存器进行设置
mov ax,8
mov bx,3
cmp ax,bx
执行后 (ax) = 8,结果是5(101B),zf = 0,pf = 1,sf = 0;of= 0,cf = 0
根据无符号指令 mov ax,bx
zf = 1,(ax) = (bx)
zf = 0;(ax) != (bx)
cf = 1;(ax) < (bx)
cf = 0 ;(ax) >= (bx)
cf = 0 and zf = 0 ;(ax) > (bx)
cf = 1 or zf = 1;(ax) <= (bx)
检测比较结果的条件转移指令
转移是指他能够修改ip,而条件是指根据某种条件,决定是否修改ip
下面是根据无符号的比较结果进行转移的条件转移指令
指令 | 含义 | 检测的相关标志位 | 英文 |
---|---|---|---|
je | 等于则转移 | zf=1 | equal |
jne | 不等于则转移 | zf=0 | no equal |
jb | 低于则转移 | cf = 1 | below |
jnb | 不低于则转移 | cf = 0 | below |
ja | 高于则转移 | cf = 0 and zf = 0 | above |
jna | 不高于则转移 | cf = 1 or zf = 1 | no above |
样例
cmp ah,bh
je s
add ah,bh
jmp short ok
s:add h,bh
ok:....
DF标志
DF标志是方向标志位(direction flag),在串处理指令中,控制每次操作后si,di的增减
df= 0 每次操作后si,di递增
df = 1,每次操作后si,di递减
对上面指令设置通常使用
cld指令:将标志寄存器的df位置0
std指令:将标志寄存器的df位置1
串传送指令
movsb
((es)*16 +(bi) ) = ((ds)*16 + (si))
当 df = 0时
(si) = (si) +1
(bi) = (bi)+1
当 df =1时
(si) = (si) -1
(bi) = (bi)-1
使用汇编表示:
mov es:[di],byte ptr ds:[si]
if df = 0
inc si
inc di
if df = 1
dec si
dec di
movsw
使用汇编表示:
mov es:[di],word ptr ds:[si]
if df = 0
add,si,2
add di,2
if df = 1
sub si,2
sub di,2
movsb 和movsw都要配合rep使用格式:rep movsb
使用汇编表示:
s:movsb
loop s
rep的作用就是根据cx的值,重复执行后面的串传送指令,由于每执行一次,movsb指令si和di都会递增或者递减指向后一单元或者前一单元
assume cs:codesgm
data segment
db "welcome to masn!"
db 16 dup(0)
data ends
codesgm segment
start:mov ax ,data
mov ds,ax
mov si,0
mov es,ax
mov di,16
mov cx,16
cld
rep movsb
codesgm ends
end start
pushf和popf
pushf的功能就是将标志寄存器的值压栈,而popf就是从栈中弹出数据,送入标志寄存器中