11.1檢測點答案
sub al,al al=0h ZF=1 PF=1 SF=0
mov al,1 al=1h ZF=1 PF=1 SF=0
push ax ax=1h ZF=1 PF=1 SF=0
pop bx bx=1h ZF=1 PF=1 SF=0
add al,bl al=2h ZF=0 PF=0 SF=0
add al,10 al=12h ZF=0 PF=1 SF=0
mul al ax=144h ZF=0 PF=1 SF=0
講解:
1首先我們認識到flag標志寄存器是記錄指令結果的狀態的。這里包括了2層含義:指令的結果(它是個值,二進制的,有的指令不影響值的變化,有的指令影響到了某個寄存器值的變化了,我們得看它的影響后的結果是什么?);根據這個結果對於flag標志寄存器的特定標志位產生了不同的值的變化。
2. 此檢測點涉及到的知識點是:
ZF是flag的第6位,零標志位,記錄指令執行后結果是否為0,結果為0時,ZF=1,它的作用:就是判斷指令的結果是否為0,與是否是有符號和無符號數無關。
PF是flag的第2位,奇偶標志位,記錄指令執行后結果二進制中1的個數是否為偶數,結果為偶數時,PF=1;
作用:在代碼傳輸的過程中,用於奇偶校驗來確定代碼(或二進制的值)在傳輸過程中是否正確被傳輸,有奇校驗和偶校驗二種。
SF是flag的第7位,符號標志位,記錄有符號運算結果是否為負數,結果為負數時,SF=1
在計算機中,使用1代表邏輯真,0代表邏輯假。
作用:對於有符號數來說,判斷正負(最高位是1,sf=1;最高位是0,sf=0),對於無符號數來說,此標志位無意義。
3.這些標志位的變化是否是自動變化的?還是手動由程序來控制的呢?
有的是自動的,有的是手動的。
4. add、sub、mul、div 、inc、or、and等運算指令影響標志寄存器
mov、push、pop等傳送指令對標志寄存器沒影響。
5.怎樣看這些標志位呢?
在調試程序DEBUG中各標志位的顯示方式(TF在DEBUG中不提供符號)
在debug中用這個指令r,在13個寄存器的最后,有類似這樣的信息: NV UP EI PL NZ NA PO NC ,它們就代表了flag狀態寄存器的值,這些值根據英文大寫的不同,代表不同的意義。
在debug中,每種標志位的狀態值都存在二種值:0和1,它們使用大寫英文來描述。例如:如遇到ZR值代表指令結果為0,NZ代表指令結果不為0;注意:它們的值在debug中,某狀態下只顯示一種值,要么是ZR要么是NZ;不能同時出現的。結合debug講解下:
這些符號代表的就是標志寄存器里常用標志位的值。這個是符號值對應表:
溢出標志OF(Over flow flag) OV(1) NV(0)
方向標志DF(Direction flag) DN(1) UP(0)
中斷標志IF(Interrupt flag) EI(1) DI(0)
符號標志SF(Sign flag) NG(1) PL(0)
零標志ZF(Zero flag) ZR(1) NZ(0)
輔助標志AF(Auxiliary carry flag) AC(1) NA(0)
奇偶標志PF(Parity flag) PE(1) PO(0)
進位標志CF(Carry flag) CY(1) NC(0)
--它們的狀態值
OF(Overflow Flag溢出標志) OV(Overflow發生溢出) NV(Non-Overflow未溢出)
SF(Signal Flag符號標志) NG(Negetive負號) PL(Plus加號,正號)
ZF(Zero Flag等於0標志) ZR(Zero為零) NZ(Non-Zero非零)
PF(Parity Flag奇偶標志) PE(Parity Even偶數) PO(Parity Odd奇數)
CF(Carry Flag進位標志) CY(Carry有進位) NC(Non-Carry無進位)
實例講解下:使用debug程序看看,r指令。
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=0B04 ES=0B04 SS=0B04 CS=0B04 IP=0102 NV UP EI PL ZR NA PE NC
紅色標注的就是這些狀態位的值,它所代表的含義看上面。
也可以使用rf指令查詢狀態寄存器的有效位的值。
-rf
NV UP EI PL ZR NA PE NC
答案講解:
sub al,al 指令結果:(al)-(al)=0 (寄存器al的值為0)
al=0h ZF=1 PF=1 SF=0
使用debug查看:
-rf
NV UP EI PL ZR NA PE NC
ZR(Zero為零) ZF=1 含義:指令結果為0;(另一種狀態值:NZ 代表ZF=0 含義:指令結果不為0 )
PE(Parity Even偶數) PF= 1 含義:指令結果中1的個數為偶數(因為al值為00000000,也就是說有0個1,0是偶數);(另一種狀態值:PO 代表ZF=1 含義:指令結果中1的個數為計數)。這個有什么含義呢?
PL(Plus加號,正號) SF=0 含義:指令結果為非負數(在計算機中,存儲0是按照計算機補碼方式存儲的,0代表的補碼含義是什么?);(另一種狀態值:NG 代表SF=1 含義:指令結果為負數)
以下同理:
特別提出:對於sf的判斷,這里就有無符號數和有符號數的理解了,快捷判斷方式是判斷它的最高位是否為1(負數)、0(正數)。在此例中,由於最高位都是0,故sf=0,
11.2答案
寫出下面每條指令執行后,ZF、PF、SF、CF、OF等標志位的值。
al CF OF SF ZF PF
sub al,al 0h/0000 0000b 0 0 0 1 1
mov al,10h 10h/0010 0000b 0 0 0 1 1
add al,90h a0h/1010 0000b 0 0 1 0 1
mov al,80h 80h/1000 0000b 0 0 1 0 1
add al,80h 0h/0000 0000b 1 1 0 1 1
mov al,0fch 0fch/1111 1100b 1 1 0 1 1
add al,05h 1h/0000 0001b 1 0 0 0 0
mov al,7dh 7dh/1111 1101b 1 0 0 0 0
add al,0bh 88h/1000 1000b 0 1 1 0 1
分析:
總結下以前學習到的標志位的含義:
CF—無符號數進位或借位標志
OF—溢出標志
SF—符號標志(0-正數;1-負數,是按照計算機補碼方式的)
ZF—零標志(1-數值為0, 0-數值為非0值)
PF—奇偶標志(1-二進制數據1個個數為偶數;0-二進制數據1個個數為奇數)
技巧:
對於CF的值判斷:直接對十六進制的操作數進行運算,得出結果,如果有進位或借位,CF=1
對於OF的值判斷:將操作數轉換成十進制數,然后運算,得出十進制結果,看是否在寄存器取值范圍內,如果超出:OF=1;
對於SF的值判斷:執行指令后的結果,最高位是1,SF就是1(負數);最高位是0,SF就是0(正數);
對於PF的值判斷:一個一個數吧。或將二進制的所有1相加,得出的十進制結果是偶數-PF=1;否則PF=0.
al CF OF SF ZF PF
sub al,al 0h/0000 0000b 0 0 0 1 1
結果中含有0個1,故PF=1
mov al,10h 10h/0010 0000b 0 0 0 1 1
mov指令不影響flag寄存器的值,故位值都不變
add al,90h a0h/1010 0000b 0 0 1 0 1
對於CF:10H+90H=A0H,沒有產生進位。CF=0
對於OF:16(10H)-112(90H)=-96,在-128~127范圍,沒有溢出。OF=0
對於SF:結果是A0H(10100000),最高位是1,SF=1
對於ZF:非0,ZF=0
對於PF:1個數是2(偶數),PF= 1
mov al,80h 80h/1000 0000b 0 0 1 0 1
mov指令不影響flag寄存器的值,故位值都不變
add al,80h 0h/0000 0000b 1 1 0 1 1
對於CF:80H+80H=100H,產生進位。CF=1
對於OF:-128(80H)-128(80H)=-256,不在-128~127范圍,溢出。OF=1
對於SF:結果是0H(00000000),最高位是0,SF=0
對於ZF:0,ZF=1
對於PF:1個數是0(偶數),PF= 1
mov al,0fch 0fch/1111 1100b 1 1 0 1 1
mov指令不影響flag寄存器的值,故位值都不變
add al,05h 1h/0000 0001b 1 0 0 0 0
對於CF:fcH+05H=101H,產生進位。CF=1
對於OF:-4(0FCH)+5(80H)=1,在-128~127范圍,不溢出。OF=0
對於SF:結果是0H(00000001),最高位是0,SF=0
對於ZF:非0,ZF=0
對於PF:1個數是1(奇數),PF=0
mov al,7dh 7dh/1111 1101b 1 0 0 0 0
mov指令不影響flag寄存器的值,故位值都不變
add al,0bh 88h/1000 1000b 0 1 1 0 1
對於CF:7DH+0BH=88H,不產生進位。CF=0
對於OF:125(7D H)+11(0BH)=136,不在-128~127范圍,溢出。OF=1
對於SF:結果是88H(10001000),最高位是1,SF=1
對於ZF:非0,ZF=0
對於PF:1個數是2(偶數),PF=1
11.3答案
(1)補全下面的程序,統計F000:0處32個字節中,大小在[32,128]的數據個數。
mov ax,0f000h
mov ds,ax
mov bx,0 ;ds:bx指向第一個字節
mov dx,0 ;初始化累加器
mov cx,32
s: mov al,[bx]
cmp al,32 ;和32進行比較
jb s0 ;如果低於al轉到s0,繼續循環
cmp al,128 ;和128進行比較
ja s0 ;如果高於al轉到s0,繼續循環
inc dx
s0: inc bx
loop s
程序解釋: jb s0(如果al變量小於32,跳轉到s0)
ja s0(如果al變量大於128,跳轉到s0)
考慮[32,128]這個數值范圍是大於等於32;小於等於128(32<=al<=128)
(2)補全下面的程序,統計F000:0處32個字節中,大小在(32,128)的數據個數。
mov ax,0f000h
mov ds,ax
mov bx,0 ;ds:bx指向第一個字節
mov dx,0 ;初始化累加器
mov cx,32
s: mov al,[bx]
cmp al,32 ;和32進行比較
jna s0 ;如果不高於al轉到s0,繼續循環
cmp al,128 ;和128進行比較
jnb s0 ;如果不低於al轉到s0,繼續循環
inc dx
s0: inc bx
loop s
程序解釋:考慮(32.128)的含義是(32<al<128)
檢測點11.4
下面指令執行后,(ax)=0045h
mov ax,0 ;(ax)=0
push ax ;將(ax)入棧
popf ;將flag寄存器的所有為都初始化為0.因為它們使用的是同一個棧結構。
mov ax,0fff0h ;(ax)=0fff0H
add ax,0010h ;執行add后,結果是:(ax)=0000H(作為無符號數,產生進位cf=1),
;作為有符號數沒有溢出,of=0;其它zf=1,sf=0,pf=1.我們把這些標志 ; 位按照順序組合起來(不能確定的我們不管了):00000xxx010x0101 ;我們不能確定的都用X表示。沒有使用的用0表示吧
pushf ;將flag的值入棧。
pop ax ;彈棧,(ax)= 00000xxx010x0101
and al,11000101B ;ax低8位按位與, 010x0101 and 11000101=01000101B=45H
and ah,00001000B ;ax高8位按位與,00000xxx and 00001000=0000000B=00H
程序分析:
1.push和popf使用的是同一個棧結構。
2.考察這個章中所學到的所有標志位的值。cf、sf、of、zf、pf代表的含義,並且對於指令結果后,這些標志位的變化。
3.如果要手動修改這些標志位,我們可以使用按位與和或的方式將ax值修改成我們期望的標志位,然后push,通過popf彈棧到flag中。
