汇编语言随笔(3)-条件转移指令和标志寄存器

标志寄存器

      标志寄存器通常具有以下三种作用:
      1,用来存储相关指令的某些执行效果
      2,用来为CPU执行相关指令提供行为依据
      3,用来控制CPU的相关工作方式
      8086CPU的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

      在8086的指令集中,运算指令的执行如:add、sub、mul、div、inc、or、and等都会影响标志寄存器;而传送指令的执行如:mov、push、pop都不会影响标志寄存器。
      1,ZF标志
      flag的第6位是ZF,零标志位。它记录了相关指令执行后,其结果是否为0,如果为0,那么ZF=1,否则,ZF=0。比如当:sub ax,ax执行后,结果为0,就会置ZF为1。
      2,PF标志
      flag的第2位是PF,奇偶标志位。它记录了相关指令执行后,其结果的所有bit位中1的个数是否为偶数。如果1的个数为偶数,PF=1,否则PF=0。如:sub ax,ax执行后,结果一共有0个1,0为偶数,因此会置ZF为1。
      3,SF标志
      flag的第7位是SF,符号标志位。它记录了相关指令执行后,其结果是否为负,如果为负,那么SF=1,否则,ZF=0。它会将操作数看作为有符号数(补码表示)的运算来记录结果的正负。如:mov al,10000001B   add al,1 执行后,结果为10000010B,SF为1。而:mov al,10000001B   add al,01111111B 执行后,-127+127=0,结果为0,它并不是一个负数,故SF为0。
      4,CF标志位
      flag的第0位是CF,进位标志位。一般情况下,在进行无符号数运算时,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。
      如:mov al,98H   add al,al   add al,al中第二条指令执行结果为98H+98H=130H,所以(al)=30H,CF=1,CF记录了从最高有效位向更高位的进位值。第三条指令执行结果为30H+30H=60H,所以(al)=60H,CF=0。
      而当两个数据做减法时,有可能向更高位借位。
      如:两个8位数据97H和98H做减法时,将产生借位,借位(置CF为1)后,97H-98H等价于197H-98H。
      5,OF标志位
      flag的第11位是OF,溢出标志位。一般情况下,OF记录了有符号数运算的结果是否发生了溢出,如果发生了溢出,OF=1,否则OF=0。
      在进行有符号数运算的时候,如果结果超过了机器所能表示的范围称为溢出。8位有符号数补码的表示范围位-128-127。
      对于 mov al,98   add al,99执行后,无符号数的结果为197,所以它不产生进位;但作为有符号数的运算,结果为197,它不在8位有符号数的表示范围内,故产生了溢出,其实它是-59的补码。所以OF=1,CF=0。
      对于 mov al,0F0H   add al,88H执行后,无符号数的结果为178H(376D),它大于255D,所以它产生进位;但作为有符号数的运算,结果为-136,它不在8位有符号数的表示范围内,(且78H为正数,两个负数相加的结果得到了一个正数)故产生了溢出。所以OF=1,CF=1。
      下面指令执行后,ZF、PF、SF、CF、OF标志位的值的变化情况。

sub al,al zf=1 pf=1 sf=0 cf=0 of=0 结果为0,0个1,未进位,正数,未溢出
mov al,10H zf=1 pf=1 sf=0 cf=0 of=0 -
add al,90H zf=0 pf=1 sf=1 cf=0 of=0 结果非0,有2个1,未进位,有符号数结果为负,未溢出
mov al,80H zf=0 pf=1 sf=1 cf=0 of=0 -
add al,80H zf=1 pf=1 sf=0 cf=1 of=1 结果为0,0个1,正数,产生进位,两负数相加结果为0,(十进制结果-256<-128)溢出
mov al,oFCH zf=1 pf=1 sf=0 cf=1 of=1 -
add al,05H zf=0 pf=0 sf=0 cf=1 of=0 结果非0,1个1,正数,产生进位,正数加负数不可能溢出,结果为01H,未溢出
mov al,7DH zf=0 pf=0 sf=0 cf=1 of=0 -
add al,0BH zf=0 pf=1 sf=1 cf=0 of=1 结果非0,2个1,负数,未产生进位,负数加负数结果为正,(十进制结果136大于127)溢出

比较指令和条件转移指令

比较指令 cmp

      比较指令 cmp,它的功能相当于减法指令,只是不保存结果。cmp指令的执行结果将对标志寄存器产生影响。其他相关指令(如条件转移指令)通过识别这些被影响的标志寄存器来得知比较结果。
      cmp指令格式:cmp op1,op2,效果为:计算op1-op2,但不保存结果,仅影响标志寄存器。如:cmp ax,ax指令执行后:zf=1,pf=1,sf=0,cf=0,of=0。
      对于cmp ax,bx,当进行无符号数运算时:
      若(ax)=(bx),则(ax)-(bx)=0,所以:zf=1;
      若(ax)!=(bx),则(ax)-(bx)!=0,所以:zf=0;
      若(ax)<(bx),则(ax)-(bx)将产生借位,所以:cf=1;
      若(ax)>=(bx),则(ax)-(bx)不会产生借位,所以:cf=0;
      若(ax)>(bx),则(ax)-(bx)不会产生借位,且不为0,所以:cf=0且zf=0;
      若(ax)<=(bx),则(ax)-(bx)可能会借位,可能会等于0,所以:zf=1或者zf=1;

      当进行有符号数运算时:
      若(ax)=(bx),则(ax)-(bx)=0,所以:zf=1;
      若(ax)!=(bx),则(ax)-(bx)!=0,所以:zf=0;
      若(ax)<(bx),如果没有发生溢出的话,那么实际存储的结果就是真实运算的结果,即of=0且sf=1;如果溢出的话,那么实际存储的结果与真实运算的结果相反,即of=1且sf=0;
      若(ax)>(bx),如果没有发生溢出的话,那么实际存储的结果就是真实运算的结果,即of=0且sf=0(当然of=0且sf=0时ax与bx也可能相等);如果溢出的话,那么实际存储的结果与真实运算的结果相反,即of=1且sf=1;

条件转移指令

      首先上一篇博文中的jcxz就是一个条件转移指令。
      下面是常用的根据无符号数的比较结果进行转移的条件转移指令:

指令 含义 检测的相关标志位
je 等于则转移 zf=1
jne 不等于则转移 zf=0
jb 低于则转移 cf=1
jnb 不低于则转移 cf=0
ja 高于则转移 cf=0且zf=0
jna 不高于则转移 cf=1或zf=1

      其中e:equal,b:below,a,above。
      虽然je进行的操作是zf=1时转移,但是我们一般是将cmp和je等条件转移指令联合起来使用,效果为:两数相等则转移。
      有符号数的比较和进行条件转移与无符号数的原理相同。这里主要是将cmp、标志寄存器的相关位、条件转移指令进行配合使用。
      例:计算F000:0处32个字节中,大小在[32,128]的数据的个数。

	mov ax,of000h
	mov ds,ax
	mov,bx,0
	mov dx,0
	mov cx,32
 s: mov al,[bx]
 	cmp al,32
 	jb s0
 	cmp al,128
 	ja s0
 	inc dx
 s0:inc bx
 	loop s

Guess you like

Origin blog.csdn.net/Little_ant_/article/details/108123374