第十一章 标志寄存器本章要点8086CPU的标志寄存器与标志寄存器相关的指令8086CPU的flag寄存器flag寄存器的作用:存储相关指令的某些执行结果;为CPU执行相关指令提供行为依据;控制CPU的相关工作方式flag寄存器的结构flag寄存器中存储的信息称为程序状态字ZF标志——Zero,零标志位它记录相关指令执行后,结果是否为0,若结果为0,ZF=1,否则ZF=0例如:mov ax,1 sub ax,1 mov ax,2 sub ax,1影响标志位的指令:运算指令一般会影响标志位,而数据传送指令不会影响标志位ZF=1ZF=0PF标志——Parity,奇偶标志位它记录相关指令执行后,结果的所有二进制位中1的个数是否为偶数,是则PF=1,否则PF=0例如:mov al,1 add al,10 mov al,1 or al,2PF=1PF=0SF标志——Sign,符号标志位它记录相关指令执行后,结果是否为负,若结果为负,则SF=1,否则SF=0SF标志,就是CPU对有符号数运算结果的一种记录,它记录数据的正负,若将数据当作有符号数来运算,可以通过它来得知结果的正负,若将数据当作无符号数来运算,SF的值没有意义。
例如:mov al,10000001B add al,1执行后,SF=1表示:若进行的是有符号数运算,则结果为负检测点11.1写出下面每条指令执行后,标志位的值CF标志——Carry,进位标志位一般情况下,在进行无符号数运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值例如:mov al,98H mov al,97H add al,al sub al,98H add al,al sub al,alOF标志——overflow,溢出标志位溢出:进行有符号数运算的时候,结果超出机器所能表示的范围机器表示的范围:8位有符号数据,机器所能表示的范围是-128~127,而16位有符号数据,机器所能表示的范围是 -32768~32767例:mov al,99 mov al,0F0h add al,99 add al, 88h进行有符号数运算时,可能发生溢出而造成结果的错误,则CPU需要对指令执行后是否溢出进行记录。
OF标志——overflow,溢出标志位一般情况下,OF记录了有符号数运算的结果是否发生了溢出,若溢出则OF=1,否则OF=0注意CF和OF的区别:CF是对无符号数运算有意义的标志位,而OF是对有符号数运算有意义的标志位例:mov al,98 add al,99 执行后,CF=0,OF=1检测点11.2写出每条指令执行后,ZF,PF,SF,CF,OF的值AF——Auxiliary Carry,辅助进位标志位 在加(减)法操作中,Bit3向Bit4(低4位向高4位)有进位(借位)时AF=1,否则AF=0ZF、PF、CF、SF、OF、AF我们统称为运算结果标志位,受算数运算和逻辑运算结果的影响 adc指令——带进位加法指令格式:adc 操作对象1,操作对象2功能:操作对象1=操作对象1+操作对象2+CF例:mov ax,2 mov ax,1mov bx,1 add ax,axsub bx,ax adc ax,3adc ax,1执行后(ax)=4 执行后(ax)=5adc指令的含义0198H和0183H相加加法可以分两步进行:低位相加高位相加在加上低位相加产生的进位值add al,bladc ah,bh等价于add ax,bx编程1计算1EF000H+201000H,结果放在ax(高16位)和bx(低16位)中程序如下:mov ax,001Ehmov bx,0F000hadd bx,1000hadc ax,0020h编程2计算1EF0001000H+2010001EF0H,结果放在ax(高16位), bx(次高16位)和cx(低16位)中程序如下:mov ax,001Ehmov bx,0F000hmov cx,1000hadd cx,1EF0hadd bx,1000hadc ax,0020h编程3 编写子程序,对两个128位数据进行相加名称:add128功能:两个128位数据进行相加参数:ds:si指向存储第一个数据的内存空间,因数据为128位,需要8个字单元,由低地址单元到高地址单元依次存放128位数据由低到高的各个字,结果存储在第一个数的存储空间ds:di指向存储第二个数据的内存空间程序如下:Add128: push ax push cx push si push di sub ax,ax mov cx,8 s: mov ax,[si] adc ax,[di] mov [si],ax inc si inc si inc di inc di loop s pop di pop si pop cx pop ax ret能否换成add si,2和add di,2 ?sbb指令——带借位减法指令指令格式:sbb 操作对象1,操作对象2功能:操作对象1=操作对象1-操作对象2-CF例如:计算003E1000H-00202000H,结果放在ax,bx中。
mov bx,1000hmov ax,003Ehsub bx,2000hsbb ax,0020hcmp指令——比较指令指令格式:cmp 操作对象1,操作对象2功能:计算操作对象1-操作对象2,不保存结果,只根据计算结果对标志寄存器进行设置 例如:mov ax,8mov bx,3cmp ax,bx执行后 (ax)=8,ZF=0,PF=1,SF=0,CF=0,OF=0cmp指令的含义cmp ax,bx(ax)=(bx),则ZF=1(ax) ≠(bx),则ZF=0(ax) <(bx),则CF=1(ax) ≥(bx),则CF=0(ax) >(bx),则CF=0且ZF=0(ax) ≤(bx),则CF=1或ZF=1反之亦成立cmp进行无符号数比较,相关标志位对比较结果的记录cmp指令的含义(续)cmp ah,bh (有符号数运算)(ah)=(bh),则ZF=1(ah) ≠(bh),则ZF=0(ah) <(bh),SF=1若cmp指令执行后,SF=1,操作对象1<操作对象2 ?mov ah,22h ;34mov bh,0A0h ; -96cmp ah,bh ;(ah)-(bh)=82H即 -126SF=1,但(ah)>(bh)因此:单纯SF的值,不能说明运算结果的正负,因为在运算过程中可能发生溢出cmp指令的含义(续)实际结果的正负和逻辑上结果的正负如果没有发生溢出,两个结果一致发生溢出,两个结果不一致因此通过SF和OF两个值,可得到逻辑结果cmp指令的含义(续)cmp ah,bhSF=1,OF=0 ;(ah)<(bh)SF=1,OF=1 ;溢出 (ah)>(bh)SF=0,OF=1 ;溢出 (ah)<(bh)SF=0,OF=0 ;(ah) ≥(bh)检测比较结果的条件转移指令条件转移指令:可以根据某种条件,决定是否修改IP的指令一类是根据cx的值决定是否转移另一类是根据某些标志的值决定是否转移根据标志位进行转移的条件转移指令常和cmp指令配合使用条件转移指令可以分为根据无符号数的比较结果进行转移的条件转移指令检测ZF、CF的值根据有符号数的比较结果进行转移的条件转移指令检测SF、OF和ZF的值根据无符号数的比较结果进行转移的条件转移指令注意:其中的标志位的值编程实现若(ah)=(bh),则(ah)=(ah)+(ah),否则(ah)=(ah)+(bh)cmp ah,bhje sadd ah,bhjmp short oks: add ah,bhok: ……je:相等则转移je:只要检测到ZF=1,就转移到相应位置执行mov ax,0add ax,0je sinc axs:inc ax(ax)=1应用条件转移指令编程例1:统计data段中数值为8的字节数,用ax保存结果data segment db 8,11,8,1,8,5,63,38data ends mov ax,data mov ds,ax mov bx,0 mov cx,8s: cmp byte ptr [bx],8 jne next inc axnext: inc bx loop s mov ax,data mov ds,ax mov bx,0 mov cx,8s: cmp byte ptr [bx],8 je ok jmp short nextok: inc axnext: inc bx loop s例2:统计data段中数值大于8的字节数,用ax保存结果mov ax,data mov ds,ax mov bx,0 mov cx,8s: cmp byte ptr [bx],8 jna next inc axnext: inc bx loop s例3:统计data段中数值小于8的字节数,用ax保存结果 mov ax,data mov ds,ax mov bx,0 mov cx,8s: cmp byte ptr [bx],8 jnb next inc axnext: inc bx loop sDF标志——状态控制标志位 flag的第10位是DF,方向标志位,在串处理指令中,控制每次操作后si,di的增减DF=0,每次操作后si,di递增DF=1,每次操作后si,di递减串传送指令传送字节串指令格式:movsb功能:将ds:si指向的内存单元中的字节送入es:di指向的单元中,然后根据DF的值,将si和di进行递增或递减传送字串指令格式:movsw功能:将ds:si指向的内存单元中的字送入es:di指向的单元中,然后根据DF的值,将si和di进行递增2或递减2两个指令可以和rep配合使用串传送指令和rep指令配合格式:rep movsb相当于: s: movsb loop s格式:rep movsw相当于: s: movsw loop srep的作用:根据cx的值,重复执行后面的串传送rep movsb可以循环实现(cx)个字符的传送DF设置指令格式: cld功能:将DF置为0格式:std功能:将DF置为1编程用串传送指令,将data段中的第一个字符串复制到它后面的空间去data segment db ‘Welcome to masm!’ db 16 dup (0)data ends分析传送的原始位置:ds:si data:0传送的目的地址:es:di data:16传送的长度:cx 16传送的方向:DF DF=0程序mov ax,datamov ds,axmov si,0mov es,axmov di,16mov cx,16cld rep movsb编程用串传送指令,将F000H段中的最后16个字复制到data段data segment db 16 dup (0)data ends传送的原始位置:F000:ffff传送的目的地址:data:15传送的长度:cx 16传送的方向:DF DF=1程序mov ax,0f000Hmov ds,axmov si,0ffffHmov ax,datamov es,axmov di,15mov cx,16stdrep movsb标志寄存器传送指令格式:pushf功能:将标志寄存器的值压栈格式:popf功能:从栈中弹出栈顶数据,送入标志寄存器上面的两条指令可以直接访问标志寄存器标志寄存器在Debug中的表示debug中对于某些标志位的表示:本章小结8086CPU标志寄存器中各标志位的含义ZF、PF、CF、SF、OF、DF、AF与标志寄存器相关的指令adc, sbbcmp,je,jne,ja,jna,jb,jnbmovsb,movsw,rep,cld,stdpushf,popf标志寄存器在debug中的表示。