1.05k likes | 1.18k Views
第 6 章 汇编语言程序设计及应用举例. 本章重点: 进一步熟悉理解 8086/8088 微处理器的指令。 掌握二进制及十进制算术运算指令及程序设计的方法,掌握 XLAT 转换指令及查表程序设计,理解位运算指令包括逻辑运算指令和移位指令及应用 . 了解串处理指令的功能,掌握常用的 DOS 功能调用和 BIOS 中断调用指令的使用方法,能综合应用汇编指令编写格式正确的汇编源程序等。. 第 6 章 汇编语言程序设计及应用举例. 6.1 算术运算程序设计 6.2 数码转换 6.3 查表程序设计 6.4 逻辑运算 6.5 字符串处理
E N D
第6章 汇编语言程序设计及应用举例 • 本章重点: • 进一步熟悉理解8086/8088微处理器的指令。 • 掌握二进制及十进制算术运算指令及程序设计的方法,掌握XLAT转换指令及查表程序设计,理解位运算指令包括逻辑运算指令和移位指令及应用. • 了解串处理指令的功能,掌握常用的DOS功能调用和BIOS中断调用指令的使用方法,能综合应用汇编指令编写格式正确的汇编源程序等。
第6章 汇编语言程序设计及应用举例 • 6.1 算术运算程序设计 • 6.2 数码转换 • 6.3 查表程序设计 • 6.4 逻辑运算 • 6.5 字符串处理 • 6.6 系统的功能调用 • 6.7 综合编程应用举例
6.1 算术运算程序设计 • 四则运算是计算机经常进行的一种操作。算术运算指令实现二进制(和十进制)数据的四则运算 • 请注意算术运算类指令对标志的影响 • 掌握:ADD/ADC/INC、SUB/SBB/DEC/ NEG/CMP • 熟悉:MUL/IMUL、DIV/IDIV • 理解:CBW/CWD、DAA/DAS、 AAA/ AAS/AAM/AAD
6.1.1 加法类指令 • 1.加法指令ADD • 功能:OPRD1←OPRD1+OPRD2 • 完成两个操作数相加,结果送至目的操作数OPRD1。目的操作数可以是累加器,通用寄存器及存储器操作数。ADD指令影响所有标志位CF、DF、PF、SF、ZF和AF。 MOV AX,2 ;(AX)=2 MOV BX,4 ;(BX)=4 ADD AX,BX ;(AX)=6
1.加法指令ADD 例如: ADD AL,30 ;累加器与立即数相加 ADD BX,[3000H] ;通用寄存器与存储单元内容相加 ADD DI,CX ;通用寄存器之间 ADD DX,DATA[BX+SI] ;通用寄存器与存储单元内容相加 ADD BUFF[SI],DX ;存储器操作数与寄存器相加
6.1 算术运算程序设计 • 2.加进位的加法指令ADC • 格式:ADC OPRD1,OPRD2 • 功能:OPRD1←OPRD1+OPRD2+CF • 这条指令与上—条指令类似,只是在两个操作数相加时,要把进位标志CF的现行值加上去,结果送至目的操作数。这条指令对标志位的影响与ADD相同。 • [例]:计算13579BDF H十02468ACE H的值。 • MOV DX,1357H • MOV AX,9BDFH • ADD AX,8ACEH ;CF=1,(AX)=26ADH • ADC DX,0246H ;(DX)=159EH
6.1 算术运算程序设计 • 格式:INC OPRD • 功能:OPRD←OPRD+1 • 完成对指定的操作数OPRD加1,然后返回此操作数。此指令主要用于在循环程序中修改地址指针和循环次数等。INC指令执行的结果不影响CF位,而对其它5个标志位AF、OF、PF、SF和ZF有影响。 • 例如: MOV AL,-2 ;(AL)= -2 ADD AL,1 ;(AL=-1,CF=0 ADD AL,1 ;(AL)=0,CF=1 ADC AL,4 ;(AL)=5,CF=0 MOV AL,-2 ;(AL)= -2 ADD AL,1 ;(AL)= -1,CF=0 INC AL ;(AL)=0,CF=0 ADC AL,4 ;(AL)=4,CF=0 • 3.加1指令INC
6.1 算术运算程序设计 1.减法指令SUB • 格式:SUB OPRD1,OPRD2 • 功能:OPRD1←OPRD1-OPRD2 • 完成两个操作数相减,也即从OPRD1中减去OPRD2,结果放在OPRD1中。 • 例如: SUB CX,BX SUB [BP],CL 6.1.2 减法类指令
6.1 算术运算程序设计 • 格式:SBB OPRD1,OPRD2 • 功能:OPRD1←OPRD1-OPRD2-CF • 这条指令与SUB类似,只是在两个操作数相减时,还要减去借位标志CF的现行值。本指令对标志位AF、CF、OF、PF、SF和ZF都有影响。同ADC指令一样,本指令主要用于多字节操作数相减。 • [例6.1.3]:计算13579BDF H-02468ACE H的值。 MOV AX,9BDFH SUB AX,8ACEH ;CF=0,(AX)=1111H MOV DX,1357H SBB DX,0246H ;(DX)=1111H 2.带借位的减法指令SBB
6.1 算术运算程序设计 • 格式:DEC OPRD • 功能:OPRD←OPRD-1 • 对指令的操作数减1,然后送回此操作数。在相减时,把操作数作为一个无符号二进制数来对待。指令执行的结果,影响标志AF、OF、PF、SF和ZF,但对CF标志不影响(即保持此指令以前的值)。 • 例如: CLC ;CF=0 MOV AX,0 ;(AX)=0,CF=0 DEC AX ;(AX)= -1,CF=0 SBB AX,3 ;(AX)= -4,CF=0 3.减1指令DEC
DEC指令对操作数减1(减量) • DEC指令不影响进位CF标志,按定义设置其他状态标志 • INC指令和DEC指令都是单操作数指令 • 主要用于对计数器和地址指针的调整
6.1 算术运算程序设计 • 格式:NEG OPRD • 功能:OPRD←0-OPRD • 对操作数取补,即用零减去操作数,再把结果送回操作数。求补运算属于减法运算,只不过被减数为0。 • 例:假设AL=4, • 执行 NEG AL后,(AL)=11111100=[-4]补 4.求补指令NEG
例:MOV AH,5 NEG AH ;AH=11111011B,是-5(补码) MOV AX,-6 NEG AX ;AX=0006H,是+6 注:操作数为0,结果不变;操作数为-128或-32768,结果数值不变,但置OF=1;NEG指令影响所有标志位。此指令的结果一般总是使标志CF=1。除非在操作数为零时,才使CF=0。 例: MOV AL,3 ;(AL)=3,CF=0 NEG AL ;(AL)=-3,CF=1 NEG AL ;(AL)=3,CF=1
6.1 算术运算程序设计 • 格式:CMP OPRD1,OPRD2 • 功能:OPRD1-OPRD2 • 比较指令完成两个操作数相减,使结果反映在标志位上,但不送回结果。 • 例如: CMP AL,100 CMP DX,DI CMP CX,COUHT[BP] CMP COUNT[SI],AX 5.比较指令CMP
6.1 算术运算程序设计 • 格式:MUL OPRD ;OPRD 为源操作数 • 完成字节与字节相乘、字与字相乘,且默认的一个操作数放在AL或AX中,而源操作数由指令给出。8位数相乘,结果为16位数,放在AX中;16位数相乘结果为32位数,高16位放在DX,低16位放在AX中。注意:源操作数不能为立即数。 6.1.3 乘法指令 1.无符号乘法指令MUL
例如: MOV AL,FIRST ;FIRST、SECOND定义为字节变量 MUL SECOND ;结果为AX=FIRST*SECOND MOV AX,THIRD ;THIRD定义为字变量 MUL AX ;结果DX:AX=THIRD*THIRD [例6.1.5]:计算255×2的值 MOV AL,-1 ;(AL)=255 MOV BL,2 MUL BL ;(AX)=510,CF=OF=1
6.1 算术运算程序设计 • 格式:IMUL OPRD ;OPRD 为源操作数 • 这是一条带符号数的乘法指令,同MUL一样可以进行字节与字节、字和字的乘法运算。结果放在AX或DX,AX中。当结果的高半部分不是结果的低半部分的符号扩展时,标志位CF和OF将置位。 2.带符号乘法指令IMUL
[例6.1.6]:计算-1×2的值 MOV AL,-1 MOV BL,2 IMUL BL ;(AX)= -2,CF=OF=0 从例子中可以看出,到底一个数是有符号数还是无符号数,由用户编程决定。 例:假设AL=0FFh,BL=0FFh 执行MUL BL ;则有AX=255×255=65025 执行IMUL BL ;则有AX=(-1)×(-1)=1
6.1 算术运算程序设计 • 除法指令包括无符号除法指令(DIV)和带符号除法指令(IDIV)两类。 • 1.无符号除法指令DIV 格式:DIV OPRD ;OPRD 为源操作数 • 2.带符号除法指令IDIV 格式:IDIV OPRD ;OPRD 为源操作数 6.1.4 除法指令
例如: MOV AX,23 MOV BL,3 DIV BL ;商(AL)=7,余数(AH)=2 [例6.1.7]:计算-2÷2的值 MOV AX,-2 MOV BL,2 IDIV BL ;(AL)= -1,(AH)=0 注意:余数的符号和被除数一致。-5/3= -1…-2=-2…+1,但计算机上,商为-1,余数是-2。
6.1 算术运算程序设计 • 3.字节扩展指令CBW • 格式:CBW ;为无操作数指令 • CBW指令对AL中的带符号数进行符号扩展;当AL<0时,AH被赋值为0FFH,否则AH被置为0。该指令不影响所有标志位。 例如: MOV AL,-2 ;(AL)=0FEH CBW ;(AX)=0FFFEH CBW指令一般与IDIV指令配合使用。当程序中需要用一个字节型带符号数去除以另一个字节型带符号数时,按IDIV指令的要求,必须把被除数(字型)放在AX中。为此,就需要用CBW指令,把存放在AL中的字节型被除数进行符号扩展变成字型带符号数。然后,才能用IDIV指令进行除法运算。
4.字转换成双字指令CWD 格式:CWD ;为无操作数指令 CWD指令将AX中的符号扩展到DX中。若AX的内容为正数,则扩展以后将0000送入DX;若AX的内容为负数,则扩展以后将0FFFF送入DX。
CBW指令和CWD指令格式中不带操作数,隐含对AL、AX中的内容进行操作。CBW指令和CWD指令格式中不带操作数,隐含对AL、AX中的内容进行操作。 例如: MOV AL,-1 ;(AL)=0FFFFH,(DX)=0 CWD ;(AX)=0FFFFH,(DX)=0FFFFH 例如: MOV AL,91h CBW ;AH=0FFh CWD ;DX=0FFFFh MOV AL,71h CBW ;AH=0 CWD ;DX=0 CWD指令的用法同CBW指令相同,与IDIV指令配合使用。不同之处是将16位的带符号数变换成32位的带符号数。
[例6.1.8]:在X1、X2、X3字节型变量中,分别存有8位带符号数Y、Z、W,写出实现(Y×Z十W)/Y的指令序列。[例6.1.8]:在X1、X2、X3字节型变量中,分别存有8位带符号数Y、Z、W,写出实现(Y×Z十W)/Y的指令序列。 解:程序如下: MOV AL,X1 ;(AL)←—Y IMUL X2 ;实现(AX)←Y*Z MOV CX,AX ;(CX)←(AX) MOV AL,X3 ;(AL)←W CBW ;扩展符号位至AH中 ADD AX,CX ;(AX)←(AX)+(CX),完成Y*Z+W IDIV X1 ;完成(Y*Z+W)/Y,商→(AL),余数→(AH)
[例6.1.9]:计算两个16位无符号数X=0E659H和Y=8DE0H的乘法运算,并将结果送DS:4000H的存储单元中(低位字放低地址,高位字放高地址)程序清单为:[例6.1.9]:计算两个16位无符号数X=0E659H和Y=8DE0H的乘法运算,并将结果送DS:4000H的存储单元中(低位字放低地址,高位字放高地址)程序清单为: MOV AX,0E659H ;取被乘数 MOV CX,8DE0H ;取乘数 MUL CX ;(AX)=92E0H,(DX)=7FA8H MOV BX,4000H ;取目标地址 MOV [BX],AX ;乘积的低位字送目标地址 INC BX INC BX MOV [BX],DX ;乘积的高位字送目标地址 INT 3 ;程序终止 若为有符号数,则执行IMUL,结果为(AX)=92E0H,(DX)=0B6FH
[例6.1.10]写出实现计算[W-(X×Y+Z-150)]/R的指令序列。假定X、Y、Z、W、R都为字变量,要求上式计算结果的商存入AX,余数存入DX寄存器。[例6.1.10]写出实现计算[W-(X×Y+Z-150)]/R的指令序列。假定X、Y、Z、W、R都为字变量,要求上式计算结果的商存入AX,余数存入DX寄存器。 MOV AX,X IMUL Y ;(DX:AX)=X×Y MOV BX,AX MOV CX,DX ;(保护结果) MOV AX,Z ;加Z CWD ADD BX,AX ;低位相加 ADC CX,DX ;高位相加 SUB BX,540 SBB CX,0 ;处理借位 MOV AX,W CWD SUB AX,BX SBB DX,CX ;计算W-(X×Y+Z—150) IDIV R ;(AX)=商,(DX)=余数
6.2 数码转换 • 1.压缩BCD码的调整指令 • DAA ;加法的十进制调整指令 • 功能:必须跟在ADD或ADC后使用,将存于AL寄存器中的2位压缩型BCD码加法运算的结果进行调整,调整后结果仍保留在AL中。调整办法: • ①调整个位。若AF=1或AL低4位>9,则(AL)+6→AL,1→AF。 • ②调整十位。若CF=1或AL高4位>9,则(AL)+60H→AL,1→CF 6.2.1 十进制调整指令
BCD码(Binary Coded Decimal),是用4位二进制数表示1位十进制数的编码方式,也称为二一十进制数,或称8421码。所以在计算机中人们用BCD码表示十进制数,对BCD码计算机中有两种表示方法:一类为压缩BCD码,即规定每个字节表示两位BCD数;另一类称为非压缩BCD码,即用一个字节表示一位BCD数,在这字节的高四位用0填充。例如,十进制数25,表示为压缩BCD数时为:25H;表示为非压缩BCD数时为:0205H,用两字节表示。相关的BCD转换指令见表6-1。
压缩BCD码就是通常的8421码;它用4个二进制位表示一个十进制位,一个字节可以表示两个十进制位,即00~99压缩BCD码就是通常的8421码;它用4个二进制位表示一个十进制位,一个字节可以表示两个十进制位,即00~99 非压缩BCD码用8个二进制位表示一个十进制位,只用低4个二进制位表示一个十进制位0~9,高4位任意,通常默认为0 6.2.1 十进制调整指令 • 十进制数调整指令对二进制运算的结果进行十进制调整,以得到十进制的运算结果 • 分成压缩BCD码和非压缩BCD码调整
[例6.2.1]:设(BCD1)=1234H,(BCD2)=6789H。求(BCD1)十(BCD2)的值。结果存BCD3中。如图6-2所示。[例6.2.1]:设(BCD1)=1234H,(BCD2)=6789H。求(BCD1)十(BCD2)的值。结果存BCD3中。如图6-2所示。 MOV AL,BCD1 ;(AL)=34H ADD AL,BCD2 ;(AL)=BDH,AF=0,CF=0 DAA ;(AL)=23H,AF=1,CF=1 MOV BCD3,AL MOV AL,BCDl+1 ;(AL)=12H ADC AL,BCD2+1 ;(AL)=7AH,AF=0,CF=0 DAA ;(AL)=80H,AF=1,CF=0 MOV BCD3+1,AL
6.2 数码转换 • 2. DAS指令 • 格式:DAS • 功能:必须跟在SUB或SBB后使用,将存于AL寄存器中的2位压缩型BCD码减法运算的结果进行调整,调整后结果仍保留在AL中。调整办法: • ①调整个位。若AF=1或AL低4位>9,则(AL)-6→AL,1→AF。 • ②调整十位。若CF=1或AL高4位>9,则(AL)-60H→AL,1→CF。
例:计算85-57的值。 MOV AL,85H SUB AL,57H ;(AL)=2EH,AF=1,CF=0 DAS ;(AL)=28H,AF=1,CF=0
6.2 数码转换 • 非压缩BCD码的调整指令 • AAA ;加法的ASCⅡ调整指令 • AAS ;减法的ASCⅡ调整指令 • AAM ;乘法的ASCⅡ调整指令 • AAD ;除法的ASCⅡ调整指令
[例6.2.2]:十进制ASCⅡ数相加。设(BCD1)=‘234’,(BCD2)=‘789’,(BCD3)=‘0000’。求解(BCD1)十(BCD2)的值。结果存BCD3中,如图6-4所示。[例6.2.2]:十进制ASCⅡ数相加。设(BCD1)=‘234’,(BCD2)=‘789’,(BCD3)=‘0000’。求解(BCD1)十(BCD2)的值。结果存BCD3中,如图6-4所示。 CLC LEA SI,BCD1+2 ;初始化 LEA DI,BCD2+2 LEA BX,BCD3+3 MOV CX,03H ;循环3次 LOP: MOV AH,0 MOV AL,[SI] ;(AL)=34H ADC AL,[DI] ;带进位加 AAA ;ASCⅡ码调整 MOV [BX],AL ;存放和 DEC SI DEC DI DEC BX LOOP LOP ;循环3次 MOV [BX],AH ;保存进位
[例6.2.3]:计算96/6=24…1。 MOV AX,0906H ;(AX)=(96)BCD MOV BL,06H ;(BL)=(03H)BCD AAD ;(AX)=0060H DIV BL ;(AL)=10H,(AH)=0 MOV DL,AH ;存余数 AAM ;(AX)=(0106H)BCD 应当注意的是,调整指令都隐含着AX或AL,都在AX或AL中进行。BCD码进行乘除法运算时,一律使用无符号数形式,因而AAM 和AAD应固定地出现在MUL之前和DIV之后。但除法的调整不同于加法、减法和乘法,除法的调整在除法操作之前进行。
[例6.2.4]:已知字变量W1和W2分别存放着两个压缩BCD数,编写程序求两数之和,并将其和送到SUM字节变量中。[例6.2.4]:已知字变量W1和W2分别存放着两个压缩BCD数,编写程序求两数之和,并将其和送到SUM字节变量中。 分析:① 定义字变量A1和A2的4位数应为BCD数,其后要加H,只有这样定义装入内存中的数据才是4位BCD数。② BCD数的加减运算只能做字节运算,不能做字运算。这是因为加减指令把操作数都当作二进制数进行运算,运算之后再用调整指令进行调整,而调整指令只对AL作为目的操作数的加减运算进行调整。 解:STACK SEGMENT STACK‘STACK’ DW 32 DUP(0) STACK ENDS DATA SEGMENT A1 DW 3456H A2 DW 6789H SUM DB 3 DUP(0) DATA ENDS
CODE SEGMENT ASSUME SS:STACK,CS:CODE,DS:DATA BEGIN: MOV AX,DATA MOV DS,AX MOV AL,BYTE PTR A1 ;AL=31H ADD AL,BYTE PTR A2 ;AL=A9H,CF=0,AF=0 DAA ;AL=09H,CF=1 MOV SUM,AL MOV AL,BYTE PTR A1+1 ;AL=89H ADC AL,BYTE PTR A2+1 ;AL=0EOH,CF=0,AF=1 DAA ;AL=46H,CF=1 MOV SUM+1,AL MOV SUM+2,0 ;处理向万位的进位 RCL SUM+2,1 ;也可用指令ADC SUM+2,0 MOV AX,4C00H ;返回DOS INT 21H CODE ENDS END BEGIN
6.3 查表程序设计 • 格式:XLAT ;AL=(DX)×16+(BX)+(AL)) • 功能:完成一个字节的查表转换。AL←(BX+AL) • 要求:①编程时BX指向表首地址。 • ②AL存放待查数据相对于表首地址的偏移量,表的大小不能超过256个字节。 • ③转换后的结果存放在AL中. 1. 转换指令XLAT
6.3 查表程序设计 • 例:内存的数据段有一张16进制数的ASCⅡ码表,首地址为Tab1,如图所示,欲查出表中第10个元素(元素序号从0开始),即‘A’的ASCⅡ码,则可用以下几条指令实现: MOV BX,OFFSET Table ;(BX)←表首址 MOV AL,0AH ;(AL)←序号 XLAT Table ;查表转换 结果‘A’的ASCⅡ码在AL中,即(AL)=41H。
2. 应用举例 [例6.3.1]:将16进制数转换为ASCⅡ码并显示出来,变量TAB1定义如图 DATA SEGMENT TAB1 DB ‘0123456789ABCDEF’;0~9,A~F的ASCⅡ码 HEX DB 5 DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV BX,OFFSET TABLE MOV AL,HEX XLAT ;AL=35H,为5的ASCⅡ码 MOV DL,Al MOV AH,02H INT 21H MOV AX,4C00H ;返回DOS INT 21H CODE ENDS END START
XLAT指令中没有明确指明操作数,而是默认采用BX和AL寄存器。XLAT指令也可用在数制转换、函数表查表、代码转换等场合。 XLAT指令中没有明确指明操作数,而是默认采用BX和AL寄存器。XLAT指令也可用在数制转换、函数表查表、代码转换等场合。 [例6.3.2]:以BUF为首地址的内存中存有1~15的平方表。查表求X单元中数(在1~15之间)的平方值,并送回X单元。 DATA SEGMENT QTab DB 1,4,9,16,25,36,49,64 DB 81,100,121,144,169,196,255 ;平方表 X DB 12 DATA ENDS STACK SEGMENT STACK‘STACK’ DB 100 DUP(?) STACK ENDS
CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK ;段地址说明 START:MOV AX,DATA MOV DS,AX ;数据段地址装填(堆栈段地址由系统装填) MOV SI,OFFSET QTab ;取QTab的偏移量 XOR AX,AX ;AX清0 MOV AL,X ;取X DEC AL ADD SI,AX ;X平方值的地址 MOV AL,[SI] ;取X的平方值 MOV X,AL ;保存在X单元 MOV AH,4CH INT 21H ;返回DOS CODE ENDS END START
填入适当指令,实现AX中十六进制数转换为ASCII码.填入适当指令,实现AX中十六进制数转换为ASCII码. MOV AX,1A78H AND AL,0FH ADD AL,30H CMP AL,3AH JL NEXT —————— NEXT:MOV [DI],AL
执行程序段后,寄存器AL 和AH 的内容分别是——,—— MOV AL,20H MOV BL,AL ADD AL,BL SBB AL,10H CBW DIV BL
执行下列程序段后,AX及IP的值分别为— MOV AX,0FFFFH MOV BX,-1 IMUL BX JMP DX
程序段分析,执行程序后,AX和DX的内容分别是——程序段分析,执行程序后,AX和DX的内容分别是—— MOV CL,4 MOV DX,248AH MOV AX,8103H ROL DX,CL MOV BH,AH SAR BH,CL SHL AX,CL OR DL,BH
6.4 逻辑运算 • 逻辑运算指令 (1)AND OPRD1,OPRD2 ;按位与操作 (2)OR OPRD1,OPRD2 ;按位或操作 (3)XOR OPRD1,OPRD2 ;按位异或操作 (4)NOT OPRD ;按位取反操作 (5)TEST OPRD1,OPRD2 ;按位与操作,不送回结果 • 逻辑运算指令除NOT指令不影响标志位外,其它指令影响SF/ZF/PF标志位,且总是使CF=0,OF=0,AF无定义。
逻辑运算指令 也称位操作指令. • 位操作类指令以二进制位为基本单位进行数据的操作;这是一类常用的指令,都应该特别掌握 • 注意:这些指令对标志位的影响 • 1、逻辑运算指令 • AND OR XOR NOT TEST • 2、移位指令 • SHL SHR SAR • 3、循环移位指令 • ROL ROR RCL RCR
6.4 逻辑运算 • 移位指令 • SAL/SHL DST,CNT ;算术左移/逻辑左移 • SHR DST,CNT ;逻辑右移 • SAR DST,CNT ;算术右移 • 移位次数CNT可以是1,若移位次数大于1时,必须放在CL中,移位结束后,CL值不变。影响AF以外的各标志位,而AF不定。
AND reg,imm/reg/mem ;reg←reg∧imm/reg/mem AND mem,imm/reg ;mem←mem∧imm/reg 1、逻辑与指令AND • 对两个操作数执行逻辑与运算,结果送到目的操作数 • 只有相“与”的两位都是1,结果才是1;否则,“与”的结果为0 • AND指令设置CF = OF = 0,根据结果设置SF、ZF和PF状态,而对AF未定义