目錄
- 各類運算時狀態標志的響應變化
- 標志符在各種`ADD`運算下的響應情況
- 標志符在各種`SUB`運算下的響應情況
- 借助標志符實現多位數之間運算
- `ADC`(add with carry)帶進位加法指令
- `SBB`(subtract with borrow)帶借位減法指令
各類運算時狀態標志的響應變化
標志符 | 具體含義 |
---|---|
CF(Carry Flag) | 進位標志CF主要用來反映運算是否產生進位或借位。如果運算結果的最高位產生了一個進位或借位,那么,其值為1,否則其值為0。 |
OF(Overflow Flag) | 溢出標志OF用于反映有符號數加減運算所得結果是否溢出。如果運算結果超過當前運算位數所能表示的范圍,則稱為溢出,OF的值為1,否則,OF的值為0 |
SF(Sign Flag) | 符號標志SF用來反映運算結果的符號位,它與運算結果的最高位相同。在微機系統中,有符號數采用補碼表示法,所以,SF也就反映運算結果的正負號。運算結果為正數時,SF的值為0,否則其值為1 |
ZF(Zero Flag) | 零標志ZF用來反映運算結果是否為0。如果運算結果為0,則其值為1,否則其值為0。在判斷運算結果是否為0時,可使用此標志位 |
在做操作數的運算時,計算機并不知道操作數是無符號數還是有符號數。因此計算機將兩種情況都考慮到了,其中CF標志符用于反映無符號數的進位與借位情況,而OF則反映有符號數的溢出情況
無符號數:其值總是非負的,二進制中沒有符號位,全用于表示值的大小。例如,8位的無符號數可表示的范圍為 0(0000 0000) ~ 255(1111 1111)
有符號數:其值有正負之分,二進制中的最高位為符號位(0表示正,1表示負),其余位則用于表示值的大小。計算機閱讀某個數將其視為有符號數時,總是將其看作是補碼(非負數補碼為其本身,負數補碼為其源碼取反再加1)的形式,例如,0000 0011 + 1111 1111 加法運算看作有符號數時,即為 (+3)+(-1)=(+2),8位的有符號數表示的范圍為 -128(1000 0000(補碼)) ~ +127(0111 1111)
標志符在各種ADD
運算下的響應情況
-
無符號數和有符號數都正常
00000011+0000010000000111\begin{array}{r} 0000\ 0011 \\ +0000\ 0100 \\ \hline 0000\ 0111 \end{array}0000?0011+0000?01000000?0111??
無符號數:3+4=73+4=73+4=7,這里顯然未產生進位,因此CF = 0
有符號數:(+3)+(+4)=(+7)(+3)+(+4)=(+7)(+3)+(+4)=(+7),這里兩個正數相加,結果也為正數,未產生溢出OF = 0 -
無符號數有溢出
00000011+11111111100000010\begin{array}{r} 0000\ 0011 \\ +1111\ 1111 \\ \hline {\color{Red} 1} \ 0000\ 0010 \end{array}0000?0011+1111?11111?0000?0010??
無符號數:3+255=2(258)3+255=2(258)3+255=2(258),這里結果為2是因為8位數的運算結果也只保留8位,顯然產生了進位即為結果最高位紅色的1,因此CF = 1
有符號數:(+3)+(?1)=(+2)(+3)+(-1)=(+2)(+3)+(?1)=(+2),這里第二個數表示為(?1)(-1)(?1)是因為上面提到的“計算機總是將有符號數看作補碼”,而兩個異號(符號位相異)的有符號數相加的結果總是在可表示范圍內(同樣只看8位結果,不將進位作為結果的一部分,而一個正數加一個負數,其結果若為正,必然不會大于該正數;結果為負,必然不會小于該負數),因此OF = 0異號兩數相加,OF總為0
-
有符號數有溢出
00000011+0111111010000001\begin{array}{r} 0000\ 0011 \\ +0111\ 1110 \\ \hline 1000\ 0001 \end{array}0000?0011+0111?11101000?0001??
無符號數:3+126=1293+126=1293+126=129,未產生進位,CF = 0
有符號數:(+3)+(+126)=(?127)(+3)+(+126)=(-127)(+3)+(+126)=(?127),兩個正數相加后結果卻為負數(加數的符號位與結果的符號位相異),顯然出現了溢出,溢出OF = 1 -
無符號數和有符號數都溢出
10000001+10000010100000011\begin{array}{r} 1000\ 0001 \\ +1000\ 0010 \\ \hline {\color{Red} 1} \ 0000\ 0011 \end{array}1000?0001+1000?00101?0000?0011??
無符號數:129+130=3(259)129+130=3(259)129+130=3(259),同第二個情況產生了進位,CF = 1
有符號數:(?127)+(?126)=(+3)(-127)+(-126)=(+3)(?127)+(?126)=(+3),同第三個情況結果與加數的符號相異,故發生溢出,OF = 1
SF標志位即為結果最高位的值,用來反映有符號數運算結果的正負性,四個情況依次為:0 0 1 0
ZF標志反映結果是否為0,四個情況結果均不為0, 故ZF均為0
標志符在各種SUB
運算下的響應情況
-
無符號數和有符號數都溢出
101110010?1001001111011111\begin{array}{r} {\color{Red} 1} \ 0111\ 0010\\ -1001\ 0011\\ \hline 1101\ 1111 \end{array}1?0111?0010?1001?00111101?1111??
無符號數:114?147=223114-147=223114?147=223,由于被減數小于減數,不夠減,這時計算機允許被減數向高位借位,因為不存在實際的高位,就體現在CF標志位,當減法運算中需要解位時,將CF標志位置1,故CF = 1,此時說明無符號數運算的溢出
有符號數:(+114)?(?109)=(?33)(+114)-(-109)=(-33)(+114)?(?109)=(?33),被減數是正數,減數是負數,正數減負數結果應該為正數,而運算結果卻為負數,說明發生了溢出,OF = 1 -
無符號數有溢出
101100011?0111110111100110\begin{array}{r} {\color{Red} 1} \ 0110\ 0011\\ -0111\ 1101\\ \hline 1110\ 0110 \end{array}1?0110?0011?0111?11011110?0110??
無符號數:99?125=23099-125=23099?125=230,同第一個情況,需要借位,故CF = 1
有符號數:(+99)?(+125)=(?26)(+99)-(+125)=(-26)(+99)?(+125)=(?26),兩個同號數相減,無論結果是正數或負數,都不會發生溢出(與加法相反,因為兩同號數相減可看作為兩異號數相加),故OF = 0同號兩數相減,OF總為0
-
有符號數有溢出
10100110?0011011001110000\begin{array}{r} 1010\ 0110\\ -0011\ 0110\\ \hline 0111\ 0000 \end{array}1010?0110?0011?01100111?0000??
無符號數:166?54=112166-54=112166?54=112,被減數大于減數,無需借位,故CF = 0
有符號數:(?90)?(+54)=(+112)(-90)-(+54)=(+112)(?90)?(+54)=(+112),負數減正數結果應該為負數,而結果卻為正數,發生了溢出,OF = 1 -
無符號數和有符號數都正常
00100110?0001001000010100\begin{array}{r} 0010\ 0110\\ -0001\ 0010\\ \hline 0001\ 0100 \end{array}0010?0110?0001?00100001?0100??
無符號數:38?18=2038-18=2038?18=20,被減數大于減數,無需借位,故CF = 0
有符號數:(+38)?(+18)=(+20)(+38)-(+18)=(+20)(+38)?(+18)=(+20),同號數相減,故OF = 0
借助標志符實現多位數之間運算
ADC
(add with carry)帶進位加法指令
不是attack damage carry
格式:ADC DST, SRC
操作:(DST) ← (DST)+(SRC)+(CF)
其中上式中的CF為運算前CF標志位的值
用16位指令實現32位的雙精度數的加法運算。設數A存放在目的操作數寄存器DX和AX,其中DX存放高位字;數B存放在寄存器BX和CX,其中BX存放高位字
;DX=2000H, AX=8000H, A=2000 8000H
;BX=4000H, CX=9000H, B=4000 9000H
ADD AX, CX ;低位字加法
ADC DX, BX ;高位字加法
-
ADD AX, CX
AX:8000H+CX:9000HAX=11000H\begin{array}{r} AX:\ 8000H \\ +\ CX:\ 9000H\\ \hline AX={\color{Red} 1} \ 1000H \end{array}AX:?8000H+?CX:?9000HAX=1?1000H??
AX寄存器值為1000H1000H1000H,產生進位CF = 1 -
ADC DX, BX
DX:2000H+BX:4000H+CF:1BDX=6001H\begin{array}{r} DX:\ 2000H\\ +\ BX:\ 4000H\\ +\ CF:\qquad {\color{Red} 1} B\\ \hline DX=6001H \end{array}DX:?2000H+?BX:?4000H+?CF:1BDX=6001H??
將CF值額外加上,即相當于加上了低位產生的進位,保證了結果的正確性,DX寄存器值為6001H6001H6001H
即20008000H+40009000H=60011000H2000\ 8000H+4000\ 9000H=6001\ 1000H2000?8000H+4000?9000H=6001?1000H
SBB
(subtract with borrow)帶借位減法指令
格式:SBB DST, SRC
操作:(DST) ← (DST)-(SRC)-(CF)
其中上式中的CF為運算前CF標志位的值
用16位指令實現32位的雙精度數的減法運算。設數A存放在目的操作數寄存器DX和AX,其中DX存放高位字;數B存放在寄存器BX和CX,其中BX存放高位字
;DX=2001H, AX=8000H, A=2001 8000H
;BX=2000H, CX=9000H, B=2000 9000H
SUB AX, CX ;低位字減法
SBB DX, BX ;高位字減法
-
SUB AX, CX
AX:18000H?CX:9000HAX=F000H\begin{array}{r} AX:\ {\color{Red} 1} \ 8000H \\ -\ CX:\quad 9000H\\ \hline AX=F000H \end{array}AX:?1?8000H??CX:9000HAX=F000H??
AX寄存器值為F000HF000HF000H,產生借位CF = 1 -
SBB DX, BX
DX:2001H?BX:2000H?CF:1BDX=0000H\begin{array}{r} DX:\ 2001H\\ -\ BX:\ 2000H\\ -\ CF:\qquad {\color{Red} 1} B\\ \hline DX=0000H \end{array}DX:?2001H??BX:?2000H??CF:1BDX=0000H??
將CF值額外減去,即相當于減去了低位向高位借走的1,保證了結果的正確性,DX寄存器值為0000H0000H0000H
即20018000H?20009000H=0000F000H2001\ 8000H-2000\ 9000H=0000\ F000H2001?8000H?2000?9000H=0000?F000H
才疏學淺,盼君指點