標志寄存器


標志寄存器(8086CPU)

作用

  1. 用來存儲相關指令的某些執行結果
  2. 用來為CPU執行相關指令提供行為依據
  3. 用來控制CPU的相關工作方式

大小

標志寄存器有16位

使用方式

標志寄存器是按位起作用,也就是說每一個位都有專門的含義,記錄特定的i西南西

flag的1、3、5、12、13、14、15位在8086CPU中沒有使用,不具有任何含義。而0、2、4、6、7、8、9、10、11位都具有特殊的含義

ZF標志,在第6位,結果為0則為1,否則為0

zf (Zero Flag) 是零標志位,在第6位;它記錄相關指令執行后,其結果是否為0,如果為0,那么zf = 1;否則zf = 0

例如

mov ax, 1
sum ax, 1

執行后, 結果為0,則zf = 1

mov ax, 2
sum ax, 1

執行后,結果不為0,則zf = 0

注意

在指令執行的過程中,有些指令對標志寄存器有影響,比如:add、sum、mul、div、inc、or、and等,他們大都是運算指令;而有些指令對標志寄存器沒有影響,比如:mov、push、pop等,他們大都是傳送指令。在使用一條指令的時候,要注意這條指令的全部功能,其中包括,執行結果對標志寄存器的哪些標志位產生了影響。

PF標志,在第2位,結果中1的個數為偶數則為1,否則為0

pf( Parity Flag)表示奇偶標志位,在第2位;他記錄的是相關指令執行后,如果所有的bit位中1的個數是否為偶數。如果1的個數位偶數,pf = 1,如果為奇數,那么pf = 0

例如:

mov al, 1
add al, 10

執行后結果為1011B,其中有3(奇數)個1,則pf = 0

mov al, 1
or al, 2

執行后,結果為:11B,其中有2(偶數)個1,則pf = 1

SF 標志,在第7位,結果為負則為1,否則為0;有符號運算有效

sf(Symbol Flag)表示符號標志位,在第7位;它記錄相關指令執行后,其結果是否為負。如果為負,則sf = 1;如果非負,sf = 0

通常CPU計算的時候有兩種方式,一種是有符號的計算,一種是無符號的計算。

SF標志,就是CPU對有符號數運算結果的一種記錄,他記錄數據的正負。

如果我們將數據進行無符號運算,SF的值則沒有意義,雖然相關指令影響了他的值

例子:

mov al, 10000001B
add al, 1

執行后,結果為10000010Bsf = 1,表示:如果指令進行是有符號運算,那么結果為負

mov al, 10000001B
add al, 01111111B

執行后,結果為0,sf = 0;表示:如果指令記性的是有符號數運算,那么結果為0

CF標志,在第0位,存儲進位或借位的值

cf(Carry Flag)表示進位標志位,在第0位。在進行無符號運算的時候,他記錄了運算結果的最高有效位向更高位的進位值,或從更高位的借位值

對於位數為N的無符號數來說,其對應的二進制信息的最高位,即第N-1為,就是他的最高位,而假想存在的第N位,就是相對於最高有效位的更高位

​ 我們都知道,在兩個數相加的時候,會往更高的位進位;比如98H + 98H,將產生進位。由於這個進位值在8位數中無法進行報錯。我之前認為這個數就丟失了。其實CPU在運算的時候,並不丟棄這個值,而是記錄在CF標志位上面。

例如

mov al, 98H
add al, al

執行后:(al) = 30H, CF = 1,CF 記錄了從最高有效位向更高位的進位值

再次執行add al, al

執行后:(al) = 60H, CF = 0, CF記錄了從最高有效位向更高位的進位值

而在做減法的時候,有可能向更高位借位;比如,兩個8位數據97H - 98H,將產生借位。借位后相當於計算197H-98H;CF來記錄這個借位值,例如下面的指令

mov al, 97H
sub al, 98H ; 執行后:(al) = FFH, CF=1, CF記錄了向更高位的借位值
sum al, al  ; 執行后:(al) = 0, CF = 0, CF 記錄了向更高位的借位值

OF標志,在第11位,結果溢出則為1,否則為0;沒理解透徹

of( Overflow Flag)表示溢出標志位,在第11位。它記錄了有符號數運算的結果是否產生了溢出,如果產生了溢出,of = 1;如果沒有,OF = 0

CPU在執行add等指令的時候,就包含了兩種含義:

  1. 無符號數運算
  2. 有符號數運算

對於無符號數運算,CPU用CF來記錄是否產生了進位;對於有符號數運算,CPU用OF來記錄是否產生了溢出。當然還要用SF來記錄結果的符號。對於無符號數運算98+99沒有進位,CF = 0;對於有符號數運算,98 + 99發生溢出,OF= 1

mov al, 0F0H
add al, 88H

add指令執行后:CF = 1, OF= 1。對於無符號數運算,0F0 + 88H有進位CF= 1, 對於有符號運算,0F0H + 88H發生溢出,OF = 1

mov al, 0F0H
add al, 78H

add指令執行后:CF = 1, OF = 0。對於無符號運算,0F0 + 78H有進位,CF = 1;對於有符號運算,0F0 + 78H不會發生溢出, OF = 0

每一個有符號數,似乎都對應着一個無符號數,我們如何知道CPU在執行運算指令的時候,進行的是有符號運算還是無符號運算呢??????????????

DF標志

df( Direction Flag), 第10位。在串處理指令中, 控制每次操作后si、di的遞減

df = 0: 每次操作后si、di遞增

df = 1:每次操作后si、di遞減

通過cld和std指令來進行設置DF的標志

然后用req movsb/movsw進行復制數據

串傳送指令movsb

ds:si指向的內存單元中的字節送入es:di中,然后根據標志寄存器df位的值,將sidi遞增或遞減

格式:movsb

功能:執行movsb指令相當於執行下面幾步操作

  1. ((es) * 16 + (di)) = ((ds) * 16 + (si))
  2. 如果df = 0則:(si) = (si) + 1, (di) = (di) + 1
  3. 如果df = 1則:(si) = (si) - 1(di) = (di) - 1

movsb的功能可以這樣描述mov es:[di], byte ptr ds:[si],但是8086CPU沒有這樣的指令。

如果df = 0

inc si
inc di

如果df = 1

dec si
dec di

串傳送指令movsw

movsw功能是將ds:si指向的內存單元中的字節送入es:di中,然后根據標志寄存器df位的值,將sidi遞增2或遞減2

movsw的功能可以這樣描述mov es:[di]. word ptr es:[si] 8086不支持這樣的指令,這里只是描述

如果df = 0

add si, 2
add di, 2

如果df = 1

sub si, 2
sub di, 2

movsb和movsw進行的是串傳送操作中的一個步驟,一般來說,movsbmovsw都和req配合使用,格式如下

reg movsb

用匯編語法來描述req movsb的功能是:

s:
  movsb
  loop s

cld和std設置DF標志位

cld 指令:將標志寄存器df位,置0

std 指令:將標志寄存器的df位,置1

adc 指令,帶位加法指令,用於計算特別大的數據

帶進位加法指令,它利用了CF位上記錄的進位值

指令格式:abc 操作對象1, 操作對象了

功能:操作對象1 = 操作對象1 + 操作對象2 + CF

比如指令:adc ax, bx實現的功能就是:(ax) = (ax) + (bx) + CF

例:

mov ax, 2
mov bx, 1
sub bx, ax
adc ax, 1

執行后,(ax) = 4。adc執行時,相當於計算:(ax) + 1 + CF = 2 + 1 + 1 = 4

mov ax, 1
add ax, ax
adc ax, 3

執行后,(ax = 5). adc執行時,相當於計算: (ax) + 3 + CF = 2 + 3 + 0 = 5

mov al, 98H
add al, al
adc al, 3

執行后,(al) = 34H。adc執行時,相當於計算:(al) + 3 + CF = 30H + 3 + 1 = 34H

可以看出,adc指令比add指令多加了一個CF位的值。

為啥要加呢?為啥要有這樣一條指令呢? 看一下兩個數據0198H和0183H

image-20191116100944518

可以看出加法是分兩步進行的

  1. 低位相加
  2. 高位相加再加上低位相加產生的進位值

下面的指令和add ax, bx具有相同的值

add al, bl
adc ah, bh

CPU提供adc指令的目的,就是來進行加法的第二步運算的,比如我們需要計算特別大的數據的時候可以采用這種方式

sbb 指令, 帶借位減法指令,用於運算特別大的數據

帶位減法指令,利用CF位上記錄的借位值

指令格式: sbb 操作對象1,操作對象2
功能:操作對象1 = 操作對象1 - 操作對象2 - CF
比如指令sbb ax, bx 實現的功能是:(ax) = (ax) - (bx) - CF

cmp指令,這個玩意有點復雜(P234, 11.8)

cmp是比較指令,cmp的功能相當於減法指令,只是不保存結果。指令執行后將對標志寄存器產生影響

指令格式: cmp 操作對象1,操作對象2
功能:計算操作對象1-操作對象2但並不保存結果,僅僅根據計算結果對標志寄存器進行設置。

比如,指令cmp ax, ax(ax)-(ax)的運算,結果為0,但並不在ax中保存,僅僅影響flag的想改給為。指令執行后:zf = 1, pf = 1, sf = 0, cf = 0, of = 0

下面的指令:

mov ax, 8
mov bx, 3
cmp ax, bx

執行后:(ax) = 8, zf = 0, pf = 1, sf = 0, cf = 0, of = 0

其實我們通過cmp指令執行后,相關標志位的值就可以看出比較的結果

cmp ax, bx

如果(ax) = (bx)(ax) - (bx) = 0, 所以zf = 1;

如果(ax) != (bx)(ax) - (bx) != 0, 所以zf = 0;

如果(ax) < (bx)(ax) - (bx) 將產生借位, 所以cf = 1;

如果(ax) >= (bx)(ax) - (bx) 不必借位, 所以cf = 0;

如果(ax) > (bx)(ax) - (bx)既不借位,結果又不為0, 所以cf = 1並且zf = 0;

如果(ax) <= (bx)(ax) - (bx) 既可能借位,結果可能為0, 所以cf = 1或zf = 1;

指令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,說明(ax)<=(bx)

以上是無符號的比較邏輯

cmp既可以對無符號進行比較,也可以對有符號進行比較,上面所說的是對無符號數進行比較時,相關標志位對比結果的記錄

有符號的比較結果

如果因為溢出導致實際結果為負,那么邏輯上真正的結果必然為正。

如果因為溢出導致實際結果為正,那么邏輯上真正的結果必然為負

pushf和popf

pushf的功能是將標志寄存器的值壓棧,而popf是從棧中彈出數據,送入標志寄存器中

pushf和popf,為直接訪問標志寄存器提供了一種方法

標志寄存器在debug中的表示


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM