第十一章 标志寄存器
1、8086CPU的标志寄存器(flag)有16位,其中存储的信息通常被称为程序状态字(PSW,program state word)。标志寄存器是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息(用0或者1表示有还是没有)
2、flag中的1、3、5、12、13、14、15在8086中没有使用,不具有任何意义。
第六位是ZF,零标志位,它记录相关指令执行后,结果为0,ZF=1,结果不为0,ZF=0。
第二位PF,奇偶标志位,记录结果的所有二进制位中1的个数,偶数,PF=1。
第七位SF,符号标志位,结果为负,SF=1。
第零位CF,进位标志位,一般来说,在进行无符号数运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。假想更高位。。
OF标志,溢出标志(溢出只是对于有符号数运算,就像进位只是相对于无符号树而言的)。
第十位是DF,方向标志位,在串处理指令中,控制每次操作后si的增减。DF=0:每次操作si,di递增,DF=1:每次操作si,di递减。
在debug中会有一下信息
3、有的指令时影响标志寄存器的,比如:add、sub、mul、div、inc、or、and等,它们大都是运算指令(进行逻辑或算数运算),有的指令的执行对标志寄存器没有影响,比如mov、push、pop等,它们大都是传送指令。我们在使用一条指令的时候,要注意这条指令的全部功能,其中包括执行结果对寄存器的哪些标志位造成影响。
4、有符号数和补码,对于同一个二进制数据,计算机可以把它当做无符号数据来运算,也可以当做有符号数据来运算。CPU在执行add指令的时候,就已经包含了两种含义,也将得到同一种信息来记录两种结果。SF标志,就是CPU对有符号数运算结果的一种记录,它记录数据的正负。关键看我们是否需要,不需要可以忽略。
5、adc指令(add carry),带进位的加法指令,它利用了CF上记录的值。CF的值是由adc前面的指令决定的。adc指令和add指令相配合就可以对更大的数据进行加法运算。inc和loop指令不影响CF位。
6、sbb带借位减法指令。(ax) = (ax) – (bx) – CF。
7、cmp比较指令,功能相当于减法指令,但不保存结果,只对标志寄存器产生影响,其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。比如:cmp ax ax,结果为0,但是并不在ax里保存,执行后ZF=1,PF=1,SF=0,CF=0,OF=0。同样cmp也包含两种含义:进行无符号数运算和进行有符号数运算。这时必须要考虑溢出。①sf=1,of=0,则ah《bh;②sf=1,of=1,则ah》bh;③sf=0,of=1,则ah《bh;④sf=0,of=0,则ah《bh。
8、检测比较结果的条件转移指令,就是检测被cmp影响的表示比较结果的标志位。因为cmp可以同时进行无符号比较和有符号数比较,所以根据cmp指令的比较结果进行转移的指令也分为两种,即①根据无符号数的比较结果进行转移的条件转移指令,检测ZF、CF的值;②根据有符号数的比较结果进行转移的条件转移指令,检测SF、OF和ZF的值。
这些指令用在cmp之后
9、DF标志和串传送指令:DF位设置:cld(clear)将DF置0,std将CF置1。格式1:movsb(以字节为单位传送),将ds:si指向内存单元中的字节送入es:di中,然后根据DF中的值si,di自增或自减。movsb和movsw跟rep搭配实现串传送,格式:rep movsb,rep的作用是根据cx的值,重复执行后面的传送指令。
10、pushf:将标志寄存器的值压栈;popf:从栈中弹出数据,送入标志寄存器中。
1 ;统计有多少个8
2 assume cs:code,ds:data
3
4 data segment
5 db 'Welcome to masm!'
6 db 16 dup(0)
7 data ends
8
9 code segment
10
11 start:mov ax,data
12 mov ds,ax
13 mov si,0 ;ds:si指向data:0
14 mov es,ax
15 mov di,16 ;es:di指向data:16
16
17 mov cx,16
18 cld ;设置DF=0,正方向传递
19 rep movsb
20
21 mov ax,4c00h
22 int 21h
23
24 code ends
25 end start