彙編語言(王爽版)學習筆記 第十一章 標誌寄存器(2)

11.8 cmp指令

cmp是比較指令,cmp的功能相當於減法指令,只是不保存結果。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

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

sf的值不能判斷大小的關鍵原因在於發生了溢出。如果沒有溢出發生的話,那麼,實際結果的正負和邏輯上真正結果的正負就一致了。

所以,我們應該再考查sf(得知實際結果的正負)的同時考查of(得知有沒有溢出),就可以得知邏輯上真正結果的正負,同時就可以知道比較的結果。

以cmp ah,bh爲例講解:
在這裏插入圖片描述


11.9 檢測比較結果的條件轉移指令

“轉移”指的是它能夠修改IP,而“條件”指的是它可以根據某種條件,決定是否修改IP。

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

編程實現如下功能:
如果(ah)=(bh)則(ah)=(ah)+(ah),否則(ah)=(ah)+(bh)。

cmp ah,bh
je s
add ah,bh
jmp short ok
	s:add ah,ah
ok:...

在這裏插入圖片描述
在這裏插入圖片描述
我們來看下面的一組程序。
data段中的8個字節如下:

data segment
	db 8,11,8,1,8,5,63,38
data ends

(1)編程,統計data段中數值爲8的字節的個數,用ax保存統計結果。

在這裏插入圖片描述
在這裏插入圖片描述

編程,統計data段中數值大於8的字節的個數,用ax保存統計結果。

在這裏插入圖片描述

編程,統計data段中數值小於8的字節的個數,用ax保存統計結果。

在這裏插入圖片描述

檢測點11.3

(1)補全下面的程序,統計F000:0處32個字節中,大小在[32,128]的數據的個數。
在這裏插入圖片描述
分析: 此處用dx保存大小在[32,128]的數據的個數。低於32跳轉到s0處進行下一次循環,高於128也跳轉到s0處進行下一次循環。

(2)補全下面的程序,統計F000:0處32個字節中,大小在(32,128)的數據的個數。
在這裏插入圖片描述

注:

cmp ah,bh
跳轉指令(以ja s0舉例)
"ja s0"表示:ah的值高於bh的值,則跳轉!
注意是前者比後者高(或低,或不高於,或不低於)

11.10 DF標誌和串傳送指令

flag的第10位是DF,方向標誌位。在串處理指令中,控制每次操作後的si、di的增減。

df=0		每次操作後si、di遞增;
df=1 	每次操作後si、di遞減。

我們來看下面的一個串傳送指令。

格式:movsb
功能:執行movsb指令相當於進行下面幾部操作
(1)((es)*16+(di))=((ds)*16+(si))
(2)如果df=0則:(si)=(si)+1;(di)=(di)+1
	如果df=1則:(si)=(si)-1;(di)=(di)-1

在這裏插入圖片描述
"movsb"表示傳送一個byte型的數據。

在這裏插入圖片描述

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

rep movsb
用匯編語法來描述 rep movsb 的功能就是:
s:movsb
	loop s
可見,rep的作用是根據cx的值,重複執行後面的串傳送指令。
由於每執行一次movsb指令si和di都會遞增或遞減指向後一個單元或前一個單元,則rep movsb就可以循環實現(cx)個字符的傳送。
rep movsw
相當於:
s:movsw
	loop s

在這裏插入圖片描述

(1)編程,用串傳送指令,將data段中的第一個字符串複製到它後面的空間中。

在這裏插入圖片描述

mov ax,data
mov ds,ax
mov si,0		;ds:si指向data:0
mov es,ax
mov di,16		;es:di指向data:0010
mov cx,16;		;(cx)=16,rep循環16次
cld
rep movsb

(2)編程,用串傳送指令,將F000H段中最後的16個字符複製到data段中。

在這裏插入圖片描述


11.11 pushf和popf

pushf的功能是將標誌寄存器的值壓棧,而popf是從棧中彈出數據,送入標誌寄存器中。
pushf和popf,爲直接訪問標誌寄存器提供了一種方法。

檢測點11.4

下面的程序執行後:(ax)=?

mov ax,0		;ax=0000
push ax			;ax=0000
popf			;ax=0000,把標誌寄存器的各位置爲0
mov ax,0fff0h	;ax=0fff0h
add ax,0010h	;ax=0fff0h+0010h=(0000)h
pushf
pop ax		
and al,11000101B
and ah,00001000B

這個要翻一下本章最開始的flag寄存器示意圖。
在這裏插入圖片描述

0fff0h+0010h=10000h;因爲產生了進位,1是進位值,ax中只能保存0000h
假設進行無符號數運算:
0fff0h+0010h=10000h,產生了進位。
假設進行有符號數運算:
-10h+10h=0,沒有產生溢出。
flag各位結果如下:
CF=1,無符號數運算產生了進位;
PF=1,奇偶標誌位ax=0000 0000h,偶數個1;
AF=1;輔助進位標誌位。運算過程中看最後四位,不論長度爲多少。最後四位向前有進位或者借位,AF=1,否則AF=0;後面4位產生了進位,AF=1;
ZF=1,ax=0000,結果爲0;
SF=0,符號標誌位,ax結果非負;
TF=0;調試標誌位。當TF=1時,處理器每次只執行一條指令,即單步執行;TF在popf的時候被置爲0;
IF=0;中斷允許標誌位。它用來控制8086是否允許接收外部中斷請求。若IF=1,8086能響應外部中斷,反之則屏蔽外部中斷;IF在popf的時候被置爲0;
DF=0;方向標誌位。在串處理指令中,每次操作後,如果DF=0,si、di遞增,如果DF=1,si、di遞減;注意此處DF的值是由程序員進行設定的 cld命令是將DF設置爲0,std命令是將DF設置爲1;DF在popf的時候被置爲0;
OF=0;溢出標誌位,沒有溢出;
標誌寄存器的其他位在popf的時候被置爲0;

flag各位如下:
在這裏插入圖片描述

pop ax之後
ah=0000 0000;al=0101 0101
and al,11000101B的結果爲 (al)=0100 0101B
and ah,00001000B的結果爲(ah)=0000 0000B
ax=0000 0000 0100 0101=69=45h

故程序執行之後,(ax)=45h.


11.12 標誌寄存器在Debug中的表示

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章