汇编学习-第十一章 目录 海伦:自学计算机编程路线 标志寄存器 CPU内部的寄存器中,有一种特殊的寄存器(对于不同的处理机,个数和结构都可能不同)具有以下3种作用。(1)用来存储相关指令的某些执行结果;(2)用来为CPU执行相关指令提供行为依据;(3)用来控制CPU的相关工作方式。 8086CPU的标志寄存器有16位,其中存储的信息通常被称为程序状态字(PSW-Program Status Word) flag寄存器是按位起作用的,它的每一位都有专门的含义,记录特定的信息。
8086CPU的指令集中,有的指令的执行是影响标志寄存器的,比如,add、sub、mul、div、inc、or、and等,它们大都是运算指令(进行逻辑或算术运算);有的指令的执行对标志寄存器没有影响,比如,mov、push、pop等,它们大都是传送指令 零标志位 (ZF) 零标志位(Zero Flag)。它记录相关指令执行后,其结果是否为0。 如果结果为0,那么zf = 1(表示结果是0);如果结果不为0,那么zf = 0。 奇偶标志位 (PF) 奇偶标志位(Parity Flag)。它记录相关指令执行后,其结果的所有bit位中1的个数是否为偶数。 如果1的个数为偶数,pf = 1,如果为奇数,那么pf = 0。 符号标志位(SF) 符号标志位(Symbol Flag)。它记录相关指令执行后,其结果是否为负。 如果结果为负,sf=1;如果非负,sf=0。 计算机中通常用补码来表示有符号数据。计算机中的一个数据可以看作是有符号数,也可以看成是无符号数。 00000001B,可以看作为无符号数1,或有符号数+1; B,可以看作为无符号数129,也可以看作有符号数-127。 对于同一个二进制数据,计算机可以将它当作无符号数据来运算,也可以当作有符号数据来运算 CPU在执行add等指令的时候,就包含了两种含义:可以将add指令进行的运算当作无符号数的运算,也可以将add指令进行的运算当作有符号数的运算 SF标志,就是CPU对有符号数运算结果的一种记录,它记录数据的正负。在我们将数据当作有符号数来运算的时候,可以通过它来得知结果的正负。如果我们将数据当作无符号数来运算,SF的值则没有意义,虽然相关的指令影响了它的值 检测11.1 各个标志位对应的值 答案如图:
进位标志位(CF) 进位标志位(Carry Flag)。一般情况下,在进行无符号数运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值
溢出标志位(OF) 溢出标志位(Overflow Flag)。一般情况下,OF记录了有符号数运算的结果是否发生了溢出。 如果发生溢出,OF = 1;如果没有,OF = 0。 CF和OF的区别:CF是对无符号数运算有意义的标志位,而OF是对有符号数运算有意义的标志位 CPU在执行add等指令的时候,就包含了两种含义:无符号数运算和有符号数运算。 对于无符号数运算,CPU用CF位来记录是否产生了进位; 对于有符号数运算,CPU用OF位来记录是否产生了溢出,当然,还要用SF位来记录结果的符号。 adc指令和sbb指令 adc是带进位加法指令,它利用了CF位上记录的进位值。 指令格式:adc 操作对象1, 操作对象2 功能:操作对象1 = 操作对象1 + 操作对象2 + CF
sbb指令 sbb是带借位减法指令,它利用了CF位上记录的借位值。 指令格式:sbb 操作对象1, 操作对象2 功能:操作对象1 = 操作对象1 – 操作对象2 – CF cmp指令 cmp是比较指令,cmp的功能相当于减法指令,只是不保存结果。cmp指令执行后,将对标志寄存器产生影响。 其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。 cmp指令格式:cmp 操作对象1,操作对象2 cpm 含义 操作对象1-操作对象2 例如: 指令cmp ax, ax,做(ax)-(ax)的运算,结果为0,但并不在ax中保存,仅影响flag的相关各位。 指令执行后:zf=1,pf=1,sf=0,cf=0,of=0。 CPU在执行cmp指令的时候,也包含两种含义:进行无符号数运算和进行有符号数运算。
如果用cmp来进行有符号数比较时 SF只能记录实际结果的正负,发生溢出的时候,实际结果的正负不能说明逻辑上真正结果的正负。 但是逻辑上的结果的正负,才是cmp指令所求的真正结果,所以我们在考察SF的同时考察OF,就可以得知逻辑上真正结果的正负,同时就知道比较的结果。 cmp ah, bh (1)如果sf=1,而of=0 。 of=0说明没有溢出,逻辑上真正结果的正负=实际结果的正负; sf=1,实际结果为负,所以逻辑上真正的结果为负,所以(ah)<(bh) (2)如果sf=1,而of=1: of=1,说明有溢出,逻辑上真正结果的正负≠实际结果的正负; sf=1,实际结果为负。 实际结果为负,而又有溢出,这说明是由于溢出导致了实际结果为负,,如果因为溢出导致了实际结果为负,那么逻辑上真正的结果必然为正。 这样,sf=1,of=1,说明了(ah)>(bh)。 (3)如果sf=0,而of=1。of=1,说明有溢出,逻辑上真正结果的正负≠实际结果的正负;sf=0,实际结果非负。而of=1说明有溢出,则结果非0,所以,实际结果为正。 实际结果为正,而又有溢出,这说明是由于溢出导致了实际结果非负,如果因为溢出导致了实际结果为正,那么逻辑上真正的结果必然为负。这样,sf=0,of=1,说明了(ah)<(bh)。 (4)如果sf=0,而of=0 of=0,说明没有溢出,逻辑上真正结果的正负=实际结果的正负;sf=0,实际结果非负,所以逻辑上真正的结果非负,所以(ah)≥(bh)。 检测比较结果的条件转移指令 可以根据某种条件,决定是否修改IP的指令 jcxz它可以检测cx中的数值,如果(cx)=0,就修改IP,否则什么也不做。 所有条件转移指令的转移位移都是[-128,127]。 多数条件转移指令都检测标志寄存器的相关标志位,根据检测的结果来决定是否修改IP 这些条件转移指令通常都和cmp相配合使用,它们所检测的标志位,都是cmp指令进行无符号数比较的时记录比较结果的标志位 根据无符号数的比较结果进行转移的条件转移指令(它们检测zf、cf的值)
j:jump,e:equal,b:below,a:above,n:not 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 movsb movsb和movsw进行的是串传送操作中的一个步骤,一般来说,movsb和movsw都和rep配合使用, 功能:rep的作用是根据cx的值,重复执行后面的串传送指令 8086CPU提供下面两条指令对df位进行设置。 cld指令:将标志寄存器的df位置0 std指令:将标志寄存器的df位置1 pushf和popf pushf的功能是将标志寄存器的值压栈,而popf是从栈中弹出数据,送入标志寄存器中 pushf和popf,为直接访问标志寄存器提供了一种方法。 实验11 编写子程序 注意是编写子程序,需要使用栈保护变量。 程序分析: 1. 根据题目,我们需要判断字符是小写字符还是大写字符,这里有条件判。 可以使用cmp指令在实现 2. “条件转移指令通常都和cmp相配合使用,它们所检测的标志位,都是cmp指令进行无符号数比较的时记录比较结果的标志位” 通常cmp 执行完会改变 zf,cf 的值,然后在利用“条件转移指令” 跳转 3. 在明确了该使用哪些指令,分析一下逻辑 1. 我们要判断是不是小写字符 ‘a’-‘z’。我们只要判断不在这个范围的就不需要处理,直接读取下一个字符。 2. 边界:判断比小的字符,读取下一个字符,jb 3. 边界:判断比大的字符,读取下一个字符,ja 4. 不在以上两个条件的,需要处理字符 5. 时刻判断字符是不是为零, je 4. 将小写字符转换为 大写字符,在第七章介绍过方法,使用and
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/66412.html