flag寄存器
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标志
零标志位
记录相关指令执行后:
如果结果为0,ZF=1
如果结果不为0,那么ZF=0
PF标志
奇偶标志位
记录相关指令执行后: 其结果所有二进制位1的个数是否为奇偶
如果1的个数为偶数,PF=1
如果1的个数为奇数,PF=0
SF标志
符号标志位
记录相关指令执行后:其结果是否为负
如果结果为负,SF=1
如果结果非负,SF=0
CF标志
进位标志位
在进行无符号数运算时,记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值
OF标志
溢出标志位
记录了有符号数运算的结果是否发生了溢出
如果发生溢出,OF=1
如果没有溢出,OF=0
adc指令
adc是带进位加法指令,它利用了CF位上记录的进位值
指令格式:adc 操作对象1,操作对象2
功能:操作对象1 = 操作对象1 + 操作对象2 + CF
比如:adc ax, bx 实现的功能是:(ax) = (ax) + (bx) + CF
编程:1EF000H + 201000H , 结果放在ax(高16位)bx(低16位)中
mov ax, 001EH
mov bx, 0F000H
add bx, 1000H
adc ax, 0020H
sbb指令
sbb是带借位减法指令,利用了CF位上记录的借位值
指令格式:sbb 操作对象1, 操作对象2
功能:操作对象1 = 操作对象1 -操作对象2 - CF
比如指令: sbb ax, bx 实现的功能:(ax) = (ax) - (bx) - CF
编程:计算003E1000H - 00202000H,结果放在ax, bx中
mov bx, 1000H
mov ax, 003EH
sub bx, 2000H
sbb ax, 0020H
cmp指令
比较指令
相当于减法指令,只是不保存结果
cmp指令执行后,将对标志寄存器产生影响。
其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果
指令格式:
cmp 操作对象1, 操作对象2
功能:
计算操作对象1 - 操作对象2 但不保存结果,仅仅根据结算结果对标志寄存器进行设置
无符号运算 相关标志位的值
有符号运算 相关标志位的值
检测比较结果的条件转移
DF标志和串传送指令
方向标志位
在串处理指令中,控制每次操作后si, di的增减
DF=0, 每次操作后si, di递增
DF=1, 每次操作后si, di递减
movsb
功能:执行movsb指令相当于进行下面几步操作:
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
功能:将ds:si只想的内存子单元中word送人es:di中,然后根据标志寄存器DF位的值,将si和di递增或递减2
1、((es)*16+(di)) = ((ds)*16+(si))
2、如果DF=0, 则 (si) = (si) + 2
(di) = (di) + 2
如果DF=1,则 (si) = (si) - 2
(di) = (di) - 2
rep
rep movsb
rep movsw
用汇编语法来描述rep movsb的功能就是:
s: movsb
loop s
功能:
根据cx的值,重复执行后面的串传送指令
由于每执行一次movsb指令si和di都会递增或递减指向后一个单元或前一个单元,则rep movsb就可以玄幻实现(cx)个字符的传送
对DF位进行设置
cld指令:将标志寄存器的DF位置0
std指令:将标志寄存器的DF位置1
pushf和popf
功能:
pushf将标志寄存器的值压栈
popf从栈中弹出数据,送入标志寄存器
TF标志
单步中断
基本上,CPU在执行完一条指令之后,如果检测到标志寄存器的TF=1,则产生单步中断,引发中断过程
单步中断的中断类型码为1
引发的中断过程:
1.取得中断类型码1
2.标志寄存器入栈,TF,IF设置为0
3.CS,IP入栈
4.(IP)=(1*4), (CS)=(1*4+2)
在Debug中使用T命令:
首先:Debug提供了单步中断的中断处理程序,功能为显示所有寄存器中的内容后等待输入命令
然后:在使用t命令执行指令时,Debug将TF设置为1,使得CPU工作于单步中断方式下,则在CPU执行完这条指令后就引发单步中断,
执行单步中断的中断处理程序,所有寄存器中的内容被显示在屏幕上,并且等待输入命令
问题:
当TF=1时,CPU在执行完一条指令后将引发单步中断,转去执行中断处理程序
注意:
中断处理程序也是由一条条指令组成的,如果在执行中断处理程序之前,TF=1,则CPU在执行完成端处理程序的第一条指令后
又将产生单步中断,则又要转去执行单步中断的中断处理程序
上面的过程将陷入一个永远不能结束的循环,CPU永远执行单步中断处理程序的第一条指令
解决方案:
在进入中断处理程序之前,设置TF=0.从而避免CPU在执行中断处理程序的时候发生单步中断
这就是为什么在中断过程中有TF=0这个步骤
响应中断的特殊情况
一般情况下,CPU在执行完当前指令后,如果检测到中断信息,就响应中断,引发中断过程
可是,在有些情况下,CPU在执行完当前指令后,即便是发生中断,也不会响应
在执行完向ss寄存器传送数据的指令后,即便是发生中断,CPU也不会响应
这样做的主要原因:
ss:sp联合指向栈顶,而对他妈的设置应该是连续完成的
如果在执行完设置ss的指令后,CPU响应中断,引发中断过程,要在栈中压入标志寄存器,CS,IP的值
而ss改变,sp并未改变,ss:sp指向的不是正确的栈顶,将引发错误
IF标志
可屏蔽中断
可屏蔽中断时 CPU可以不响应的外中断
CPU是否响应可屏蔽中断,要看标志寄存器的IF位的设置
当CPU检测到可屏蔽中断信息时
如果IF=1,则CPU在执行完当前指令后响应中断,引发中断过程
如果IF=0,则不响应可屏蔽中断
因为可屏蔽中断信息来自CPU外部,中断类型码时通过数据总线送入CPU的
而内中断的中断类型码是在CPU内部产生的
现在,可以解释中断过程中将IF设置为0的原因了,将IF置为0的原因就是,在进入中断处理程序后,禁止其他的可屏蔽中断
设置IF的指令:
sti ;设置IF=1 cli ;设置IF=0
不可屏蔽中断
不可屏蔽中断时CPU必须响应的外中断
当CPU检测到不可屏蔽中断信息时,则在执行完当前指令后,立即响应,引发中断过程
对于8086CPU,不可屏蔽中断的中断类型码固定为2