轉載必須注明出處,違者必究。http://www.cnblogs.com/dennisOne
☞標志寄存器綜述
-
8086CPU的標志寄存器(flags Register, FR)有16位,其中存儲的信息通常被稱為程序狀態字(PSW),flag寄存器與其他寄存器不同,flag寄存器是按位起作用的。8086的flag寄存器中有CF、PF、ZF、SF、OF、DF標志位。

- 8086的FR的9個標志位
標志位
名稱
功能
ZF
零標志位(Zero Flag)
判斷結果是否為0。運算結果0,ZF置1,否則置0。
PF
奇偶標志位(Parity Flag)
反映運算結果低8位中'1'的個數。'1'的個數為偶數,PF置1,否則置0。
SF
符號標志位(Sign Flag)
反映運算結果的符號。運算結果為負,SF置1,否則置0。
CF
進位標志位(Carry Flag)
反映無符號運算是否產生進位或借位。運算結果的最高有效位向更高位進位或者借位,CF置1,否則置0。
OF
溢出標志位(Overflow Flag)
反映有符號運算是否溢出。運算結果超過了8位或者16位有符號數的表示范圍,OF置1,否則置0。
AF
輔助進位標志位(Auxiliary Flag)
在字節操作時低半字節向高半字節進位或借位。字操作時低字節向高字節進位或借位,AF置1,否則置0。
DF
方向標志位(Direction Flag)
決定串處理指令控制每次操作后si、di的增減。df=0,則每次操作后si、di遞增,否則遞減。
IF
中斷標志位(Interrupt Flag)
決定CPU是否響應外部可屏蔽中斷請求。IF為1時,CPU允許響應外部的可屏蔽中斷請求。
TF
陷阱標志位(Trap Flag)
TF被設置位1時,CPU進入單步模式,所謂單步模式就是CPU在每執行一步指令后都產生一個單步中斷。主要用於程序的調試。8086/8088中沒有專門用來置位和清零TF的命令。
-
影響標志位的指令
- 在8086CPU的指令集中,諸如add/sub/mul/div/inc/or/and這些邏輯或者算術運算影響FR;而諸如mov/push/pop等傳送指令的執行不影響FR。
- 執行一條指令,要注意這條指令的全部功能(特別是cmp),執行結果對FR的那些標志位造成影響。
- 某些指令將影響FR中的多個標志位。
-
修改標志位的常用方法
-
pushf和popf提供了直接訪問標志寄存器的一種方法。
pushf的功能是將標志寄存器的值壓棧;而popf是從棧中彈出數據。比如:
pushf ; 將FR的值壓棧
pop ax ; (ax)=(FR)
; 處理ax
push ax ; 將修改后的(ax)壓棧
popf ; (FR)=(ax)
-
sub ax, ax 可以將CF設置為0,ZF設置為0。
-
修改DF
cld ; 將DF置為0
std ; 將DF置為1
-
-
FR在debug中的表示

| 標志位 |
=1 |
=0 |
| ZF |
ZR[Zero] |
NZ[Not Zero] |
| PF |
PE[Parity Even] |
PO[Parity Odd] |
| SF |
NG[Negative] |
PL[Plus] |
| CF |
CY[Carry] |
NC[No Carry] |
| OF |
OV[Overflow] |
NV[Not Overflow] |
| AF |
AC[Auxiliary Carry] |
NA[No Auxiliary Carry] |
| DF |
DN[Down] |
UP[UP] |
| IF |
EI[Enable Interrupt] |
DI[Disable Interrupt] |
| TF |
------------------------------ |
-------------------------------- |
☞從CPU的角度看待指令
以下列指令進行講解:
mov al, 10000001B
add al, 1
- CPU在執行add等指令的時候,就已經包含了兩種含義(有符號和無符號運算),也將得到同一種信息來記錄的兩種結果。關鍵在於我們的程序需要哪一種結果。
- 通過FR的PSW,我們可以根據需要來看待指令進行的運算。
- 可以講add指令進行的運算當做無符號數的運算,那么add指令相當於計算129+1,結果是130(10000010B);也可以將add指令進行的運算當做有符號的運算,那么add指令相當於-127+1,結果也就是-126(10000010B)。
☞adb指令和sbb指令
| 指令 |
指令格式 |
功能 |
示例 |
| 帶進位加法指令adc |
adc op1, op2 |
op1=op1+op2+CF |
adc ax,bx |
| 帶借位減法指令sbb |
sbb op1, op2 |
op1=op1-op2-CF |
sbb ax,bx |
Q: 編寫一個程序,對兩個128位數據進行相加。
1 assume cs:code, ds:code 2 3 data segment 4 db 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h, 88h 5 db 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h, 11h 6 data ends 7 8 code segment 9 start: mov ax, data 10 mov ds, ax 11 mov si, 0 12 mov di, 8 13 14 mov cx, 8 15 16 call add128 17 18 mov ax, 4c00h 19 int 21h 20 21 add128: ; 子程序開始 22 push ax 23 push cx 24 push si 25 push di 26 27 sub ax, ax ; 將CF置0 28 29 mov cx, 8 30 s: mov ax, [si] 31 adc ax, [di] 32 mov [si], ax 33 inc si ; inc不會影響CF的值;但是add si,2會影響CF的值 34 inc si 35 inc di 36 inc di 37 loop s 38 39 pop di 40 pop si 41 pop cx 42 pop ax 43 44 ret 45 code ends 46 end start
☞DF標志和串傳遞指令
| 指令 |
功能 |
解釋 |
| movsb |
傳送字節單元 |
mov es:[di], byte ptr ds:[si] ;8086不支持這樣的指令,這里示意 如果df=0 inc si inc di 如果df=1 dec si dec di |
| movsw |
傳送字單元 |
mov es:[di], word ptr ds:[si] ;8086不支持這樣的指令,這里示意 如果df=0 add si, 2 add di, 2 如果df=1 sub si, 2 sub di, 2 |
| rep movsb |
串傳送 |
s: movsb loop s rep的作用是根據cx的值,重復執行后面的串傳送指令。 |
| rep movsw |
串傳送 |
s: movsw loop s |
☞cmp指令
-
cmp指令概述
cmp是比較指令,cmp的功能相當於減法指令,但是不保存結果[猜測:CPU可能使用不能被外界使用的某個寄存器進行暫存?]。cmp指令執行后,將對標志寄存器產生影響。
| 指令格式 |
功能 |
示例 |
| cmp op1, op2 |
計算op1-op2,但不保存結果,僅僅根據結果對標志寄存器產生影響。 |
cmp ax, ax |
- 和sub指令一樣,CPU在執行cmp指令時,也包含兩種含義:進行無符號數和有符號數運算。
-
cmp ax, bx當做"無符號數運算"的含義[根據zf和cf進行解釋]

反過來:

根據無符號數的比較結果進行轉移的條件轉移指令(短轉移)的原理就是基於上表。

-
cmp ax, bx當做"有符號數運算"的含義[根據zf/sf/of進行解釋]
【公理】:進行有符號數運算時,如果發生溢出(of=1),說明實際運算結果與邏輯運算結果不等;如果沒有溢出(of=0),說明實際運算結果與邏輯運算結果一致。

☞cmp指令和條件轉移指令的聯合使用


總結:題(1)中"等於"和題目(2)中"大於"需要進行特別處理,所以應該講"不等於"和"不大於"的直接跳出,這樣可以使得程序更加簡潔。
