给出下列各指令执行后AL的值以及CF,ZF,SF,OF和PF的状态。
MOV AL,89H ;第1行
ADD AL,AL ;第2行
ADD AL,9DH ;第3行
CMP AL,0BCH ;第4行
SUB AL,AL ;第5行
DEC AL ;第6行
INC AL ;第7行
这类题解题步骤是:
1.先算无符号数
2.再算有符号数(无符号数取反加一或是根据原理)
3.判断各标志位
具体步骤如图:
注:什么是原理法?
原理法的用途: 多用于判断有符号数的原码
先查看无符号数的运算结果(无符号数运算结果的补码). 其最高位为0则是正数, 正数的补码与原码一样, 直接得出该正有符号数的原码既是无符号数运算结果的补码.
其最高位为1则是负数, 负数从-128算起, 加上除最高位以外的别的位组成的二进制数对应的十进制正数, 即得该负有符号数的十进制表示,(从十进制转为二进制就是它的原码了, 但一般我们得到其十进制表示又何必再转回原码呢?)
原理法的原理: 补码表:
补码表:
我们看到无符号数129的二进制码是10000001, 最高位为1, 其可代表负有符号数, 从表上我们看到, 负有符号数是从-128开始算起的, 我们把129的二进制码10000001拆成10000000+1,10000000就是-128, -128再加上拆出来的1就是-127, 即10000001是有符号数-127的补码. 进而二进制补码10000001的原码是-127的二进制表示.
第1行执行后:
AL | 二进制表示 | 无符号数 | 有符号数 | CF ZF SF OF PF |
---|---|---|---|---|
89H | 10001001 | 137 | -119 | 0 0 0 0 0 |
1.先算无符号数:
89H = (10001001)2 = (137)10
2.再算有符号数:
方法一:(取反加一)
(10001001)2 = (01110110)全反 (01110110)全反 +1 = (01110111)补 = (119)有符号数的绝对值 则该有符号数就是119*(-1) = -119
注:全反就是符号位也取反
方法二:(原理法)
(10001001)2 的最高位符号位为1, 则有符号数为负数, 负数从-128算起, (-128)10= (10000000)2
(10001001)2 除最高位之外的位为我们要加上的数(00001001)2 = (9)10 ,则-128+9=(-119)有符号数
3.MOV指令不改变标志位, 故各标志位均为0
第2行执行后:
AL | 二进制表示 | 无符号数 | 有符号数 | CF ZF SF OF PF |
---|---|---|---|---|
12H | 00010010 | 18 | 18 | 1 0 0 1 1 |
1.先算无符号数:
137+137 = 274
但是274超过了8位无符号数的表示范围(无符号:0~255, 有符号:-128~127), 此次之行必会引来进位操作, 故CF=1
先从137加到255: 137+? = 255, ? = 255-137 = 118需要加118才能到255, 那么先把137拆成118和19, 先加118:
137+118=255,再把19拆成1和18, 先加1: 255+1 = 256这里开始超出表示范围了, 那么加了1以后AL变为0, 再把剩下的18加上, 得此时的AL存储的是无符号数的话值为0+18 = 18.
2.再算有符号数:
在算有符号数之前,我们很容易发现有符号运算已经发生溢出, -119+(-119) = -238 < -128. 于是得到错误的结果"18"
但这个18不是溢出造成的, 而是进行无符号数运算时的结果, 也就是说步骤1里面的137+137产生进位后的结果. 我们所说的错误结果"18"并不是算数意义上的错误结果, 它是指在有符号数运算中这个结果没有实际意义. 但这不代表他在算数意义上是错误的, 因为从无符号数的角度来看它是无符号数的正确运算结果, 也就是说, 如果有符号数运算发生溢出, 那么这个结果就不用看了, 它只能指代无符号数的结果, 不代表有符号数的结果.
12H = (00010010)2 最高位符号位为0, 如果该数表示有符号数, 则为正, 结果与无符号数一样为18
3.再看各标志寄存器:
运算结果不为零ZF=0, 结果非负SF=0, 运算结果最高位符号位由1变为0, 产生溢出OF=1, 结果的1的个数为2为偶数PF=1
第3行执行后:
AL | 二进制表示 | 无符号数 | 有符号数 | CF ZF SF OF PF |
---|---|---|---|---|
0AFH | 10101111 | 175 | -81 | 0 0 1 0 1 |
1.先算无符号数:
(9DH)16 = (157)10 18+157 = 175 < 255 故无符号数运算结果为175 未发生进位 CF=0 , 结果也不为零 ZF=0
(157)10 = (10101111)2 结果中"1"的个数为6, 为偶数个, PF=1
2.再算有符号数:
(9DH)16 = (10011101)2 这个(10011101)2 是有符号数的补码, 为了得到其源码, 对(10011101)2 取全反加一后得: (01100011)2
(01100011)2 = (99)有符号数绝对值 则有符号数为(99)*(-1) = -99 原码为(11100011)2
则 -99+18 = -81>-128 结果未发生溢出OF=0 结果为负数 SF=1
3.再看各标志寄存器:
综上所述, 标志寄存器依次为 0 0 1 0 1.
第4行执行后:
AL | 二进制表示 | 无符号数 | 有符号数 | CF ZF SF OF PF |
---|---|---|---|---|
0AFH | 10101111 | 175 | -81 | 1 0 1 0 1 |
[注]CMP指令本身含有操作数1-操作数2的意义, 根据相减结果的正负来判断是大于还是小于, 但它不会修改寄存器中的值. 在本题中其比较结果没有意义, 于是只关心它做减法运算的功能.
1.先算无符号数:
CMP AL,0BCH 相当于 (AL) - 0BCH
(0BCH)16 = (188)10 175-188<0
发生借位 CF=1 发生借位后的运算结果是175+256-188 = 243 243不为零ZF=0
(243)10 = (11110011)2 共有6个"1", 个数为偶数, PF=1
2.再算有符号数:
(0BCH)16 = (10111100)2 原理法算得0BCH有符号数原码是-128+60 = -68
-81-(-68) = -13 <0 则SF=1
3.再看各标志寄存器:
综上所述, 标志寄存器依次为 1 0 1 0 1.
第5行执行后:
AL | 二进制表示 | 无符号数 | 有符号数 | CF ZF SF OF PF |
---|---|---|---|---|
00H | 00000000 | 0 | 0 | 0 1 0 0 1 |
1.先算无符号数:
SUB AL,AL 毫无疑问就是0
2.再算有符号数:
SUB AL,AL 毫无疑问就是0
3.最后看各标志寄存器:
结果为0则ZF=1, 没发生进位/借位 CF=0, 结果非负SF=0, 没发生溢出OF=0, 结果中"1"的个数为0则PF=1(0是偶数)
第6行执行后:
AL | 二进制表示 | 无符号数 | 有符号数 | CF ZF SF OF PF |
---|---|---|---|---|
0FFH | 11111111 | 255 | -1 | 0 0 1 0 1 |
1.先算无符号数:
0-1<0发生借位, 则借位后的运算结果为0+256-1 = 255, (255)10 = (11111111)2 ZF=0, PF=1
值得注意的是DEC指令的减法不影响CF, 故CF=0, 同理INC指令的加法也不影响CF
2.再算有符号数:
原理法: -128+127 = -1
则SF=1
3.最后看各标志寄存器:
综上所述, 标志寄存器依次为 0 0 1 0 1.
第7行执行后:
AL | 二进制表示 | 无符号数 | 有符号数 | CF ZF SF OF PF |
---|---|---|---|---|
00H | 00000000 | 0 | 0 | 0 1 0 0 1 |
1.先算无符号数:
255+1>255发生进位, 则进位后的运算结果为255+1-256 = 0, ZF=1,PF=1
第六行执行的时候提到了, INC不影响CF, 故CF=0
2.再算有符号数:
方法一:就是上一次有符号数结果加一:-1+1 = 0 则SF=0, OF=0
方法二:原理法,00000000 的原码还是0, 0的补码还是00000000, 故结果为0
3.最后看各标志寄存器:
综上所述, 标志寄存器依次为 0 1 0 0 1.