flag标志寄存器

flag标志寄存器_第1张图片

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标志

进位标志位

  在进行无符号数运算时,记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值

flag标志寄存器_第2张图片

 

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     但不保存结果,仅仅根据结算结果对标志寄存器进行设置

 

无符号运算  相关标志位的值

 flag标志寄存器_第3张图片

 

有符号运算  相关标志位的值

 flag标志寄存器_第4张图片

 

 

 检测比较结果的条件转移

flag标志寄存器_第5张图片

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

 

你可能感兴趣的:(flag)