title: 汇编笔记_第十一章
date: 2018-12-30 14:00:51
tags:
- 笔记
categories: - 汇编语言
标志寄存器
标志寄存器的作用:
-
用来存储相关指令的某些执行结果
-
用来为CPU执行相关指令提供行为依据
-
用来控制CPU的相关工作方式
-
标志寄存器由16位,按位起作用,0,2,4,6,7,8,9,10,11有特殊的含义,其他的没有任何含义;
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
OF | DF | IF | TF | SF | ZF | AF | PF | CF |
标志位的符号
零标志ZF(Zero flag) | ZR(1) | NZ(0) |
奇偶标志PF(Parity flag) | PE(1) | PO(0) |
符号标志SF(Sign flag) | NG(1) | PL(0) |
进位标志CF(Carry flag) | CY(1) | NC(0) |
溢出标志OF(Over flow flag) | OV(1) | NV(0) |
方向标志DF(Direction flag) | DN(1) | UP(0) |
中断标志IF(Interrupt flag) | EI(1) | DI(0) |
辅助标志AF(Auxiliary carry flag) | AC(1) | NA(0) |
零标志ZF
flag的第6位
它记录相关指令执行后,
- 结果为0,ZF=1;
- 结果非零,ZF=0;
例如:
mov ax,1
sub ax,1
mov ax,1
and ax,0
指令执行后,结果为0,则ZF=1;
mov ax,2
sub ax,1
mov ax,1
or ax,1
指令执行后,结果为1,则ZF=0;
在8086CPU的指令集中,有的指令的执行事影响标志寄存器的,例如:add,sub,mul,div,inc,or,and等。有的不影响,如:mov push,pop等传送指令;
奇偶标志PF
flag的第二位
它记录指令执行后,结果的所有二进制位中1的个数:
- 为偶数,PF=1;
- 为奇数,PF=0;
例如:
mov al,1
add al,10
执行后,PF=0;
mov al,1
or al,10
执行后,PF=1;
符号标志SF
flag的第七位
它记录指令执行后:
- 结果为负,SF=1;
- 结果为正,SF=0;
mov al,10000001b
add al,1
执行后SF=1;
进位标志CF
flag的第0位
在进行 无符号数运算 的时候,它记录的运算结果的最高有效位项更高位的进位值,或从更高位的借位值;
例:
mov al,98h
add al,al ;(al)=30h,cf=1
add al,al ;(al)=30h,cf=1
溢出标志OF
flag的第11位
在进行 有符号数运算 的时候,如果结果超出了及其所能表示的范围称为溢出;
溢出时OF=1;
注意:
- CF是对 无符号 数运算有意义的标志位;
- OF是对 有符号 数运算有意义的标志位;
例如:
mov al,0F0H
add al,78H
CF=1,OF=0;
对于无符号运算,0F0H+78H有进位,CF=1;对于有符号数运算,不发生溢出,OF=0;
例如:
sub al,al
;0h=0000 0000b
;CF=0 OF=0 SF=0 ZF=1 PF=1
mov al,10h
;10h=0001 0000b
;CF=0 OF=0 SF=0 ZF=1 PF=1
add al,90h
;90h=1001 0000b
;ans=1010 0000b
;CF=0 OF=0 SF=1 ZF=0 PF=1
mov al,80h
;80h=1000 0000b
;CF=0 OF=0 SF=1 ZF=0 PF=1
add al,80h
;80h=1000 0000b=128d
;ans=1 0000 0000b=256d
;CF=1 OF=1 SF=0 ZF=1 PF=1
mov al,0FCH
;0FCH=1111 1100b=252d
;CF=1 OF=1 SF=0 ZF=1 PF=1
add al,05h
;05h=0000 0101b
;ans=1 0000 0001b=257d
;CF=1 OF=0 SF=0 ZF=0 PF=0
mov al,7DH
;7DH=0111 1101b=125d
;CF=1 OF=0 SF=0 ZF=0 PF=0
add al,0BH
;0BH=0000 1011b=11d
;ans=1000 1000b=136d
;CF=0 OF=1 SF=1 ZF=0 PF=1
总结:
- CF只看八位二进制计算后的第九位的值
- OF看计算后的值是否在-128~127内
- SF只看有符号数的第8位
- ZF看8位是否都为0
- PF看8位里的1的个数
- 标志寄存器的改变仅在非传送指令执行时
adc指令
adc是带进位加法指令,他利用了CF位上记录的进位值;
格式:
adc 操作对象1,操作对象2
功能:
操作对象1=操作对象2+CF
例如:adc ax,bx
==(ax)=(ax)+(bx)+CF
mov ax,2
mov bx,1
sub bx,ax
adc ax,1
(ax)=(ax)+1+CF=4
mov al,98h
add al,al
adc al,3
(ax)=(ax)+3+CF=30H+3+1=34H
- adc指令和add指令相配合可以对更大的数据进行加法运算;
- adc指令加上CF值的含义由adc之前的指令决定,如果CF是由sub设置,它的含义就是借位值,由add设置就是金为珩值;
编写一个对两个128位进制数据进行相加的子程序:
add128:
push ax
push cx
push si
push di
sub ax,ax ;置CF为零
mov cx,8
s:
mov ax,[si]
adc ax,[si]
mov [si],ax
inc si
inc si
inc di
inc di
;注意这里只能这么写,不能改成add si,2,否则会置CF为零
loop s
pop di
pop si
pop cx
pop ax
sbb指令
sbb是带借位减法指令,利用了CF位上记录的借位值
格式:
sbb 操作对象1,操作对象2
功能:
操作对象1=操作对象1-操作对象2-CF
比如:
sbb ax,bx
实现:(ax)=(ax)-(bx)-CF
sbb指令执行后,将对CF进行设置;
cmp指令
cmp是比较指令,功能相当于减法指令,但 不保存结果;
cmp指令执行后,将对标志寄存器产生影响;
格式:
cmp 操作对象1,操作对象2
功能:计算操作对象1-操作对象2
不保存结果,仅仅根据计算结果对标志寄存器进行设置;
例如:
cmp ax,ax
ZF=1
PF=1
SF=0
CF=0
OF=0
cmp ax,bx
指令执行后,可以根据相关的标志位的值看出比较的结果:
如果(ax)=(bx) | (ax)-(bx)=0 | ZF=1 |
如果(ax) ( eq) (bx) | (ax)-(bx) ( eq) 0 | ZF=0 |
如果(ax) (lt) (bx) | (ax)-(bx)将产生借位 | CF=1 |
如果(ax) (ge) (bx) | (ax)-(bx)不必借位 | CF=0 |
如果(ax) (gt) (bx) | (ax)-(bx)既不必借位,结果又不为零 | CF=0并且ZF=0 |
如果(ax) (le) (bx) | (ax)-(bx)既可能借位,结果可能为零 | CF=1或ZF=1 |
cmp与add、sub一样既可以对无符号数比较也可以对有符号数比较;
不能单纯的看SF的值来判断两个操作对象的大小,因为溢出的问题;
cmp ah,bh
- 如果SF=1,OF=0:OF=0说明没有溢出,逻辑上真正的结果的正负和实际结果的相同;SF=1,实际结果为负,所以逻辑上为负,(ah) (lt) (bh);
- 如果SF=1,OF=1:因为溢出导致实际结果为负,那么逻辑上真正结果为正,说明 (ah) (gt) (bh);
- 如果SF=0,OF=1:因为溢出导致实际结果为正,那么逻辑上真正的结果必然为负,说明 (ah) (lt) (bh);
- 如果SF=0,OF=0: (ah) (ge) (bh);
条件转移指令
所有条件转移指令的转移位移是[-128,127];
通常和cmp相配合;
cmp指令的比较结果进行转移的指令分为:
- 根据 无符号整数 的比较结果进行转移的条件转移指令,检测ZF、CF的值;
- 根据 有符号整数 的比较结果进行转移的条件转移指令,检测SF、OF、和ZF的值;
根据无符号数的比较结果进行转移的条件转移指令:
指令 | 含义 | 检测的相关标志位 |
---|---|---|
je | 等于则转移 | ZF=1 |
jne | 不等于则转移 | ZF=0 |
jb | 低于则转移 | CF=1 |
jnb | 不低于则转移 | CF=0 |
ja | 高于则转移 | CF=0,ZF=0 |
jan | 不高于则转移 | CF=1或ZF=1 |
DF标志和串传送指令
flag的第10位
功能:在串处理指令中,控制每次操作后si,di的增减;
- DF=0:每次操作后si,di递增;
- DF=1:每次操作后si,di递减;
格式1:movsb
功能:以字节为单位传送;
- ((es)16+(di))=((ds)16+(si))
- if(df==0): (si)=(si)=1,(di)=(di)+1;
- if(df=0): (si)=(si)-1,(di)=(di)-1;
格式2: movsw
功能:以字为单位传送
rep mobsb
or rep movsw
一般,movsb
和 movsw
和 rep
配合使用,rep的作用是根据cx的值,重复执行后面的串传送指令;
对DF位的设置:
cld
指令:将标志寄存器的DF位置0std
指令:将标志寄存器的DF位置1
例如:
data segment
db 'Welcome to masn!'
db 16 dup(0)
data ends
;将data段中的第一个串送到后面的空间
;传送的设置:
;传送的原始位置:ds:si
;传送的目的地址:es:di
;传送的长度:cx
;传送的方向:DF
mov ax,data
mov ds,ax
mov si,0
mov es,ax
mov di,16
mov cx,16
cld
rep movsb
pushf和popf
pushf
: 将标志寄存器的值压栈popf
: 从栈中弹出数据,送入到标志寄存器中
https://www.cnblogs.com/31415926535x/p/10200283.html
(end)