标志位寄存器
标志 真值位1 真值位0
OF OV NV
SF NG PL
ZF ZR NZ
PF PE PO
CF CY NC
DF DN UP
16bit = 0或者1
运算的信息状态(F = flag)
CF标志寄存器(carry flag)
CF CY NC
CY(carry yes) 进位 NC not carry(不进位)
和运算指令有关 运算指令会影响标志位
mov push pop 这些指令不会影响标志位
在进行无符号运算的时候,它纪录了运算结果的最高有效位向更高位的进位值,或从更高位的错位值。CF只针对无符号数(将寄存器中的操作数看成无符号数)
ZF标志寄存器(zero)
ZF ZR NZ
ZR是 Zero
NZ是not zero
用来判断某一指令的运算结果是否是0
指令执行后,其结果是否为0,若结果为0,那么ZF=1;如果不为0,那么ZF=0。
div和mul不影响标志位
PF标志寄存器(Parity flag)
parity(奇偶性)
PF PE PO
PE是EVEN 偶数
PO是ODD 奇数
bit = 0或者1
0000 0011B (1出现了2次,是偶数)
0000 0111B (1出现了3次,是奇数)
指令执行后,其结果的二进制表示中1的个数是否为偶数,若1的个数为偶数,PF=1;若1的个数为奇数,PF=0。
SF标志寄存器(Sign flag)
Sign 是符号的意思
SF NG PL
NG是gegative(负数)
PL是positive(正数)
0000 0000 ~ 0111 1111B 0~127
1000 0000 ~ 1111 1111B 0~-128
- 有符号运算
指令执行后,其结果是否为负。若结果为负,SF=1;如果非负,SF=0。
两个数相加,结果转换成二进制,看最高位,若为1,SF=1,若为0,SF=0。
OF标志位(overflow)
-128~127 有符号数
-32768~32767
overflow是溢出
OF OV NV
OV是overflow溢出
NV是not overflow 没有溢出
在进行有符号运算的时候,如结果超过了机器所能表示的范围称为溢出。OF针对有符号数(将寄存器中的操作数看成有符号数)
判断OF时,默认为有符号运算,先把数值换成补码形式,看补码的数值是否在[-128,+127]范围之内
mov al,0F0H ;F0H转换成补码为-16
add al,088H ;88H转换成补码为-120
执行后,将产生溢出,因为超出了范围
OF与CF的区别
OF是有符号数 -128~127
CF是无符号数 0~256
DF标志寄存器
DF DN UP
DN就是Down(向下)
UP就是up(向上)
IF标志位位于标志寄存器第9位,名称为方向标志位,默认为0
- 当DF为1时,存储器地址自动减少,串操作指令为自动减量指令。
- 当DF为0时,存储器地址自动增加,串操作指令为自动增量指令。
可通过汇编指令CLD将DF标志位设置为0,也可通过STD将DF设置为1。
串操作指令包含MOVSB,MOVSW,MOVSD。
要将DS:SI后面的100字节数据复制到ES:DI开始的内存区域:
mov cx, 100
cld
rep movsb
如果是将DS:SI前面的100字节数据复制到ES:DI前面的内存区域:
mov cx, 100
std
rep movsb
测试
adc指令(带进位加法)
ADC(带进位加法)指令将源操作数和进位标志位的值都与目的操作数相加。该指令格式与 ADD 指令一样,且操作数大小必须相同:
add ax,bx ;ax = ax + bx
adc ax,bx ;ax = ax + bx + carry
例如,下述指令实现两个 8 位整数相加 (FFh+FFh),产生的 16 位和数存入 DL:AL,其值为 01FEh:
如下:
mov ax,0FFFFH
mov dx,1000h
add ax,0FFFFH
abc dx,0
sbb指令(带进位减法)
sbb(带进位减法)指令将源操作数和进位标志位的值都与目的操作数相减。该指令格式与 sub 指令一样,且操作数大小必须相同:
sub ax,bx ;ax = ax - bx
sbb ax,bx ;ax = ax - bx - carry
mov dx,1000
mov ax,0005
sub ax,6
sbb dx,0
cmp指令
sub ax,bx ax = ax-bx
cmp ax,bx 修改标志位
ax = bx zf = 1相等
ax != bx zf = 0 不相等
ax
ax>=bx cf = 0 大于等于
ax>bx cf = 0 并且 zf = 0
ax
je 相等则跳转
jne 不相等则不跳转
jb 小于则跳转
jnb 大于等于则跳转
ja 大于则跳转
jna 小于等于则跳转
cmp指令的一些问题
如果溢出导致了实际结果为负,那么逻辑上真正的结果必然为正
如果溢出导致了实际结果为正,那么逻辑上真正的结果必然为负
pushf和popf
这里的 f 代表 flag
pushf 就是把flag放到栈中
mov ax,0 ax = 0000 0000 0000 0000
push ax
popf psw(标志寄存器) = 0000 0000 0000 0000
;把16位标志寄存器全部设置为0
mov ax,0FFF0H ax = 0FFF0H
add ax,0010H psw = 0000 0000 0100 0101
pushf
pop ax ax = 0000 0000 0100 0101
and al,1100 1001B ax
and ah,0000 1000B