微機原理與接口技術(shù)課件:指令系統(tǒng)與匯編語言_第1頁
微機原理與接口技術(shù)課件:指令系統(tǒng)與匯編語言_第2頁
微機原理與接口技術(shù)課件:指令系統(tǒng)與匯編語言_第3頁
微機原理與接口技術(shù)課件:指令系統(tǒng)與匯編語言_第4頁
微機原理與接口技術(shù)課件:指令系統(tǒng)與匯編語言_第5頁
已閱讀5頁,還剩249頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

指令系統(tǒng)與匯編語言3.1指令格式與尋址方式3.2

8086/8088CPU指令系統(tǒng)3.3匯編語言的程序與語句3.4匯編語言的偽指令3.5匯編語言程序設(shè)計基礎(chǔ)3.6

DOS功能子程序的調(diào)用本章小結(jié)學(xué)習(xí)目標(biāo)

學(xué)習(xí)匯編語言程序設(shè)計,必須掌握微處理器的指令系統(tǒng)。本章先以8086微處理器為例介紹微型計算機的指令系統(tǒng),包括指令格式、尋址方式和各類指令功能。要求讀者明確各種尋址方式的區(qū)別和特點,掌握有效地址和物理地址的計算方法,要正確使用指令,掌握各類指令的功能、對標(biāo)志位的影響和使用上的一些特殊限制。匯編語言是面向微處理器編程的一種高效的程序設(shè)計語言,通常用來編寫對時間和空間要求較高的程序。要求讀者掌握匯編語言的基本結(jié)構(gòu)、語法規(guī)則及一些基本要求,通過程序?qū)嵗龑W(xué)習(xí)程序設(shè)計的基本方法,包括循環(huán)、分支和子程序等基本結(jié)構(gòu),以及宏匯編技術(shù)與DOS功能調(diào)用,并能夠編寫基本匯編程序,初步掌握匯編程序的編寫和調(diào)試方法,能夠閱讀和編寫簡單的匯編語言程序。

學(xué)習(xí)重點

(1)操作碼、操作數(shù)的基本概念。

(2)8086的6種基本尋址方式及有效地址的計算。

(3)各類指令的匯編格式、功能、對標(biāo)志位的影響和注意事項。

(4)匯編語言源程序的書寫規(guī)則、語句基本格式及程序的分段結(jié)構(gòu)。

(5)常用的偽指令語句的格式、功能及應(yīng)用。

(6)順序結(jié)構(gòu)、分支結(jié)構(gòu)、循環(huán)結(jié)構(gòu)程序和子程序的基本結(jié)構(gòu)與設(shè)計方法。

(7)常用DOS功能調(diào)用的方法,包括鍵盤輸入、顯示輸出和系統(tǒng)時間的功能調(diào)用。

3.1指令格式與尋址方式

3.1.1指令格式

指令格式是指令的編碼格式,其體現(xiàn)了指令系統(tǒng)的概貌,說明了指令系統(tǒng)的機器目標(biāo)代碼是如何構(gòu)成的。指令通常由操作碼段和操作數(shù)段兩部分組成:

(1)操作碼段給出計算機要執(zhí)行的具體操作(如傳送、運算、移位、跳轉(zhuǎn)等),是指令中必不可少的組成部分。

(2)操作數(shù)段說明在指令執(zhí)行過程中參與該操作的對象,它可以是操作數(shù)本身,也可以是操作數(shù)地址或是地址的一部分,還可以是指向操作數(shù)地址指針或其他有關(guān)操作數(shù)據(jù)的信息。單地址指令的操作只需一個操作數(shù),如加1指令:INCAX。大多數(shù)運算指令都需要兩個操作數(shù),如加法指令:ADDAX,BX;運算的結(jié)果送到AX中,AX稱為目的操作數(shù),BX稱為源操作數(shù)。

操作數(shù)的種類又可分為數(shù)據(jù)操作數(shù)和轉(zhuǎn)移地址操作數(shù)。

(1)數(shù)據(jù)操作數(shù):指令中操作的對象是數(shù)據(jù),包括立即數(shù)操作數(shù)、寄存器操作數(shù)、存儲器操作數(shù)和I/O操作數(shù)。

(2)轉(zhuǎn)移地址操作數(shù):這類操作數(shù)是與轉(zhuǎn)移地址有關(guān)的操作數(shù),即指令中操作的對象不是數(shù)據(jù),而是要轉(zhuǎn)移的目標(biāo)地址。轉(zhuǎn)移地址操作數(shù)也可分為:立即數(shù)操作數(shù)、寄存器操作數(shù)和存儲器操作數(shù)。也就是說,要轉(zhuǎn)移目標(biāo)的地址包含在指令中,或存放在寄存器中,或存放在存儲單元中。3.1.2尋址方式

在指令中可以直接給出操作數(shù)的值,或者給出操作數(shù)存放的地址。CPU可根據(jù)指令字中給出的地址信息求出存放操作數(shù)的有效地址EA(EffectiveAddress),對存放在有效地址中的操作數(shù)進行操作。指令中關(guān)于如何求出操作數(shù)有效地址的方法即為操作數(shù)的尋址方式,計算機按照指令給出的尋址方式求出操作數(shù)有效地址和存取操作數(shù)的過程被稱為尋址操作。根據(jù)指令中操作數(shù)所存放位置的不同,8086CPU的尋址方式有兩類:數(shù)據(jù)尋址方式和轉(zhuǎn)移地址尋址方式。

1.數(shù)據(jù)的尋址方式

1)立即數(shù)尋址

立即數(shù)尋址方式所提供的操作數(shù)直接包含在指令中,其緊跟在操作碼的后面,與操作碼一起被放在代碼段區(qū)域中。因而,立即數(shù)總是與操作碼一起被取入CPU的指令隊列,在指令執(zhí)行時不需再訪問存儲器。立即尋址方式僅用于源操作數(shù),主要是用來給寄存器或存儲器賦初值。

立即數(shù)可以是8位或16位數(shù)。若立即數(shù)是16位的,則其低8位字節(jié)存放在相鄰兩個存儲單元的低地址單元中,高8位字節(jié)則存放在高地址單元中。例如:

MOVAX,1234H ;將立即數(shù)1234H送入累加器AX

MOV[2100H],12H ;將立即數(shù)12H送入2100H的存儲單元

2)寄存器尋址

寄存器尋址即為寄存器直接尋址。在此尋址方式中,操作數(shù)存放在指令規(guī)定的CPU內(nèi)部寄存器中。對于16位操作數(shù),寄存器可以是AX、BX、CX、DX、SI、DI、SP或BP;對于8位操作數(shù),寄存器可以是AL、AH、BL、BH、CL、CH、DL或DH。例如:

INCCX ;CX內(nèi)容加1,結(jié)果送回CX

MOVCL,DL ;DL內(nèi)容送至CL

MOVDS,AX ;AX內(nèi)容送至DS

顯然,對于寄存器尋址方式而言,由于操作數(shù)就在CPU的寄存器中,不需要訪問總線即可獲取操作數(shù),因而采用這種尋址方式的指令具有較高的執(zhí)行速度。

2.存儲器尋址方式

在存儲器尋址方式中,操作數(shù)存放在存儲單元中,因此,在指令中可以直接或間接地給出存放操作數(shù)的有效地址EA,以達到訪問操作數(shù)的目的。

1)直接尋址

直接尋址是存儲器直接尋址的簡稱,是一種最簡單的存儲器尋址方式。在這種尋址方式下,指令中的操作數(shù)部分直接給出操作數(shù)的有效地址EA(16位的偏移地址),且該地址與操作碼一起被放在代碼段中。通常,在直接尋址方式中,操作數(shù)放在存儲器的數(shù)據(jù)段(DS)中,這是一種默認的方式。

此外,如果要對除DS段之外的其他段(如CS、ES、SS)中的數(shù)據(jù)尋址,則應(yīng)在指令中增加段前綴,用以指出當(dāng)前段段寄存器名,此稱為段超越——在有關(guān)操作數(shù)的前面加上段寄存器名,再加上冒號“:”。例如:

MOVAX,[1000H];將DS段中1000H單元內(nèi)容送至AX

MOVAX,ES;[2000H];將ES段中2000H單元內(nèi)容送至AX

2)寄存器間接尋址

在寄存器間接尋址方式中,操作數(shù)存放在存儲區(qū)中,其有效地址EA為一個由指令規(guī)定的基址寄存器(BP、BX)或變址寄存器(SI、DI)的內(nèi)容,即應(yīng)注意,在書寫該類指令時,必須用方括號“[]”將用作間接尋址的寄存器括起來,以免與前面介紹的寄存器尋址方式混淆。例如:MOVAX,[SI] ;將[SI]為有效地址的存儲器單元中的操作數(shù)送至AX,默認DS為

;當(dāng)前段基寄存器

MOV[BP],CX ;將CX的內(nèi)容送至以[BP]為有效地址的存儲器單元中,默認SS為

;當(dāng)前段基寄存器

這種尋址方式可用于表格處理(即訪問連續(xù)存儲單元)。此時,在執(zhí)行完一條指令后,只需修改寄存器內(nèi)容就可以取出表格中的下一項。

3)寄存器相對尋址

在這種尋址方式中,操作數(shù)存放在存儲單元中,其有效地址EA等于一個由指令規(guī)定的基址寄存器?(BP、BX)?或變址寄存器?(SI、DI)?的內(nèi)容與由指令中給定的8位或16位的相對地址位移量之和,即

寄存器相對尋址方式的操作數(shù)在匯編語言中的書寫也可以采用多種形式。例如:

MOV[SI+disp],AX ;將AX內(nèi)容送至有效地址為?[SI+disp]?的存儲單元中

MOVdisp[SI],AX ;與上一條指令同

MOV[SI]+disp,AX ;與上一條指令同

寄存器相對尋址方式也允許段超越。在缺省段超越前綴時,BX、SI、DI默認的段寄存器為DS,BP默認的段寄存器為SS。例如:

MOVBX,[VALUE+DI] ;默認DS為當(dāng)前段寄存器

MOVSS:STR0[SI],AX ;“SS”是段超越前綴,即SS為當(dāng)前段寄存器

4)基址變址尋址

這種尋址方式中操作數(shù)的有效地址EA等于一個基址寄存器(BX或BP)與一個變址寄存器(SI或DI)的內(nèi)容之和,即

基址變址尋址方式的操作數(shù)的書寫形式也可有多種。例如:

MOVAL,[BX+SI]

MOV[BP][DI],AX

基址變址尋址方式允許段超越。在缺少段超越前綴時,BX默認的段寄存器為DS,BP默認的段寄存器為SS。

注意,該尋址方式的基址寄存器只能是BX或BP,而變址寄存器只能是SI或DI。

這種尋址方式同樣可用于數(shù)組和表格處理。在進行處理時,可將首地址放在基址寄存器中,而用變址寄存器來訪問數(shù)組或和表格中的各個元素。

3.?I/O端口尋址方式

CPU與外部設(shè)備之間的信息交換通過I/O接口電路來實現(xiàn)。每個I/O接口都有一個或幾個端口(Port),每個端口被分配的地址號稱為端口地址。一個端口通常是I/O接口電路內(nèi)部的一個或一組寄存器。

在8086/8088指令系統(tǒng)中,必須通過專門的輸入/輸出指令(IN/OUT)訪問I/O端口。IN/OUT指令對I/O端口的尋址方式有兩種:

(1)直接端口尋址。該尋址方式用于8位I/O端口的尋址,8位I/O端口地址(00H~FFH)以立即數(shù)的形式在指令中直接給出。可尋址的端口地址范圍為0~255。例如:

INAL,21H ;從端口地址為21H端口中讀取數(shù)據(jù),送到AL中

(2)間接端口尋址。該尋址方式是針對16位I/O端口的尋址,類似于寄存器間接尋址。在間接端口尋址時,應(yīng)事先將16位I/O端口地址(0000H~0FFFFH)存放在規(guī)定的DX寄存器中,即通過DX對端口間接尋址。該尋址方式可尋址的端口號的范圍為0~65?535。例如:

MOVDX ,350 ;將端口地址350送到DX中

OUTDX,AL ;將AL中的內(nèi)容輸出至由(DX)所指定的端口中

3.2

8086/8088?CPU指令系統(tǒng)

8086/8088?CPU的指令可分為六大類:

(1)數(shù)據(jù)傳送類指令(Datatransferinstructions)。

(2)算術(shù)運算類指令(Arithmeticinstructions)。

(3)位操作類指令(Bitmanipulationinstructions)。

(4)串操作類指令(Stringinstructions)。

(5)控制轉(zhuǎn)移類指令(Programtransferinstructions)。

(6)處理器控制類指令(Processorcontrolinstructions)。3.2.1數(shù)據(jù)傳送類指令

數(shù)據(jù)傳送類指令的傳送數(shù)據(jù)可以是某些變量的內(nèi)容、地址或標(biāo)志寄存器內(nèi)容。使用該類指令既可以在寄存器之間進行數(shù)據(jù)傳送,亦可在寄存器與存儲單元之間進行數(shù)據(jù)傳送。這類指令分為4類,共有14條,見表3-1。由表可知,僅SAHF和POPF指令影響標(biāo)志位。1.通用數(shù)據(jù)傳送指令

1)傳送指令MOV

指令格式:

MOVdest,src ;dest?←?(src)

功能:將源操作數(shù)的內(nèi)容傳送給目的操作數(shù)。MOV指令對標(biāo)志寄存器(FR)的各位無影響。在MOV指令中,兩個操作數(shù)可以是字,也可以是字節(jié),但兩者必須等長。例如:

MOVAX,BX ;寄存器之間傳送AX?←?BX

MOV[3000H],DX ;將DX中內(nèi)容傳送到存儲器3000H單元

MOV[SI],DS ;將DS中的內(nèi)容傳送到SI所指示的單元

在使用MOV指令時,應(yīng)注意以下幾點:

(1)段寄存器CS僅能作源操作數(shù),不能作為目的操作數(shù);

(2)源操作數(shù)和目的操作數(shù)不能同時為存儲單元操作數(shù)(串操作指令除外);

(3)立即數(shù)不能直接傳送給段寄存器,且不同的段寄存器之間不能進行直接傳送。

2)交換指令XCHG

指令格式:

XCHGoprd1,oprd2;(oprd1)

(oprd2)

功能:源操作數(shù)和目的操作數(shù)的內(nèi)容相互交換。該指令對標(biāo)志寄存器的各位均無影響。

在該指令中,交換的數(shù)據(jù)可以是字節(jié),也可以是字。數(shù)據(jù)交換可以在寄存器之間或寄存器與存儲器之間進行。例如:XCHGAX,BX和XCHGBX,[BP+SI]?指令。3)堆棧操作指令PUSH/POP

指令格式:

PUSHsrc;SP?←?(SP)?-?2,(SP)+1:(SP)?←?(src)

POPdest;dest?←?[(SP)+1:(SP)],SP?←?(SP)+2

功能:對堆棧的信息進行存取。堆棧操作不影響標(biāo)志寄存器。

PUSH:先修正堆棧指針SP,然后將16位源操作數(shù)壓入堆棧,先高位后低位。例如:PUSH?AX。若給定(SP)?=?00F8H,(SS)?=?2500H,(AX)?=?5120H,則指令執(zhí)行后(SP)?=?00F6H,(250F6H)?=?5120H。

POP:從棧頂彈出16位操作數(shù)到目的操作數(shù),然后,修改堆棧指針SP,使SP指向新的棧頂。例如:PUSH?BX。若給定(SP)?=?0100H,(SS)?=?2000H,(BX)?=?78C2H,(20100H)?=?6B48H,則指令執(zhí)行后(SP)?=?0102H,(BX)?=?6B48H。

在程序設(shè)計中,堆棧是一種十分有用的結(jié)構(gòu)。其經(jīng)常用于子程序的調(diào)用與返回、保存程序中的某些信息,以及在輸入輸出系統(tǒng)中的中斷響應(yīng)和返回。8086/8088堆棧的使用規(guī)則如下:

(1)堆棧的使用要遵循后進先出(LIFO)的準(zhǔn)則;

(2)堆棧中操作數(shù)的類型必須是字操作數(shù),不允許以字節(jié)為操作數(shù);

(3)?PUSH指令可以使用CS寄存器,但POP指令不允許使用CS寄存器;

(4)?8086/8088CPU堆棧操作可以使用除立即尋址以外的任何尋址方式。

2.地址傳送指令

地址傳送指令完成的操作是傳送存儲器操作數(shù)的地址(偏移量、段基址),而不是傳送存儲器操作數(shù)的內(nèi)容。這組指令對標(biāo)志寄存器各標(biāo)志位均無影響,指令中的源操作數(shù)都必須是存儲器操作數(shù),而目的操作數(shù)可以是任何一個16位的通用寄存器。

1)裝入有效地址LEA

指令格式:

LEAreg16,mem16 ;?reg16?←?EA[mem16]

功能:將當(dāng)前段內(nèi)的源操作數(shù)的有效地址EA(地址偏移量)傳送至目的操作數(shù),即將一個16位的近地址指針寫入到指定的16位通用寄存器中。例如:

LEABX,BUFFER ;將變量BUFFER的地址偏移量傳送至BX

LEADI,BETA[BX][SI] ;將內(nèi)存單元的地址偏移量傳送至DI

LEA指令可用在表格處理、存取若干連續(xù)的基本變量的處理和串操作處理中,為寄存器建立地址指針。例如:

MOVDI,TABLE ;將變量TABLE的內(nèi)容傳送至DI

LEADI,TABLE ;將變量TABLE的地址偏移量傳送至DI

MOVDX,[1000H] ;將內(nèi)存單元[1000H]、[1001H]的內(nèi)容送至DX

LEADX,[1000H] ;將1000H送至DX2)裝入遠地址指針LDS/LES

指令格式:

LDSreg16,mem32 ;reg16?←?EA[mem32],DS?←?EA[mem32]+2

LESreg16,mem32 ;reg16?←?EA[mem32],ES?←?EA[mem32]+2

功能:將源操作數(shù)所對應(yīng)的4字節(jié)內(nèi)存單元中的第一個字送入指定的通用寄存器,而第二個字則送入段寄存器DS(或ES),即將一個32位的遠地址指針的偏移地址寫入到指定的通用寄存器中,而該指針的段基址送至段寄存器DS(或ES)。例如:

LDSSI,[0200H] ;SI?←?EA[0200H],DS?←?EA[0202H]

假設(shè),當(dāng)前(DS)?=?3000H,存儲單元?[30100H]?=?80H,[30101H]=20H,[30102H]=00H,[30103H]=25H。則執(zhí)行以上指令后,(SI)=2080H(偏移地址),(DS)?=

2500H(段基址)。

地址傳送類指令LEA、LDS、LES常用于串操作時,需建立初始的串地址指針。

3.標(biāo)志寄存器傳送指令

CPU中各標(biāo)志寄存器FLAG(FR),其中的每一個狀態(tài)標(biāo)志位代表CPU運行的狀態(tài)。許多指令的執(zhí)行結(jié)果會影響FR的某些狀態(tài)標(biāo)志位;同時,有些指令的執(zhí)行也受FR中某些位的控制。標(biāo)志寄存器傳送類指令共有4條,專門用于對標(biāo)志位寄存器的保護或更新。

1)標(biāo)志寄存器讀/寫指令

指令格式:

LAHF;AH?←?(FR)的低8位

SAHF;FR的低8位(AH)

LAHF:把標(biāo)志寄存器的低8位讀出后傳送給AH寄存器。

SAHF:把寄存器AH中的內(nèi)容寫入標(biāo)志寄存器。

【例3-1】

若希望修改標(biāo)志寄存器中的SF位,如置“1”,可首先用LAHF指令把含有SF標(biāo)志位的標(biāo)志寄存器的低8位送入AH;然后,對AH的第7位(其對應(yīng)于SF位)進行修改或設(shè)置;最后用SAHF指令送回標(biāo)志寄存器。實現(xiàn)以上操作的程序段為:

LAHF ;FR的低8位送到AH

ORAH,80H ;邏輯“或”指令,將SF位置“1”

SAHF ;AH的內(nèi)容返回到FR2)標(biāo)志寄存器壓棧/彈棧指令

指令格式:

PUSHF ;SP?←?(SP)?-?2;(SP)+?1:?(SP)?←?(FR)

POPF ;FR?←?[(SP)+?1:(SP)];SP?←?(SP)+?2

PUSHF:首先修改堆棧指針,然后將16位標(biāo)志寄存器的所有標(biāo)志位送入SP指向的堆棧頂部字單元中。

POPF:將當(dāng)前棧頂?shù)囊粋€字傳送到16位標(biāo)志寄存器,同時修改堆棧指針。

上述兩條指令中,標(biāo)志寄存器中各標(biāo)志位本身不受影響。指令PUSHF常用于保護調(diào)用過程以前的標(biāo)志寄存器的值,

而在過程返回以后,再利用指令POPF恢復(fù)出這些標(biāo)志狀態(tài)。

利用指令PUSHF/POPF,可以方便地改變標(biāo)志寄存器中任一標(biāo)志位狀態(tài)。

【例3-2】可以用下面的程序段來修改TF標(biāo)志,將TF位置“1”:

PUSHF ;保護當(dāng)前FR的內(nèi)容

POPAX ;FR的內(nèi)容送至AX

ORAH,01H ;將TF位置“1”

PUSHAX

POPF

;AX的內(nèi)容送至FR

4.輸入/輸出數(shù)據(jù)傳輸指令I(lǐng)N/OUT

這組指令專門用于累加器(AL或AX寄存器)與I/O端口之間的數(shù)據(jù)傳輸。其中,輸入指令I(lǐng)N用于從外設(shè)端口接收數(shù)據(jù),輸出指令OUT用于向外設(shè)端口發(fā)送數(shù)據(jù)。

指令格式:

IN累加器,port ;累加器?←?[port]

OUTport,累加器 ;port?←?(累加器)

8088/8086?CPU中有16條I/O地址線,可提供64?K個8位端口(port8)地址或32?K個16位端口地址。在使用I/O數(shù)據(jù)傳送指令I(lǐng)N/OUT時,應(yīng)注意:

(1)當(dāng)端口地址小于256(即地址為00H~FFH)時,采用直接尋址方式;

(2)當(dāng)端口地址等于或大于256(即地址為0100H~FFFFH)時,采用間接尋址方式(當(dāng)然,端口地址為00H~FFH時,也可使用間接尋址方式),即事先將端口地址放在DX寄存器中,然后,再使用I/O指令。例如:

INAX,20H ;從端口20H輸入16位數(shù)到AX

OUT28H,AL ;將8位數(shù)從AL輸出到端口28H

例如:

MOVDX,3F3H

;將16位端口地址3F3H存入DX

INAX,DX

;從端口3F3H輸入16位數(shù)到AX

OUTDX,AX

;將16位數(shù)從AX輸出到端口3F3H3.2.2算術(shù)運算類指令

8086/8088?CPU的算術(shù)運算指令支持加、減、乘、除4種基本運算,指令的操作對象可以是以下4種類型的數(shù)據(jù):無符號二進制數(shù)、帶符號二進制數(shù)、無符號壓縮十進制數(shù)(壓縮BCD碼)和符號非壓縮十進制數(shù)(非壓縮BCD碼)。

若操作對象是帶符號數(shù),則用補碼表示。8086/8088的算術(shù)運算類指令如表3-2所示。

8086?CPU的算術(shù)運算指令的執(zhí)行結(jié)果都影響標(biāo)志位。這些標(biāo)志中的絕大多數(shù)可由跟在算術(shù)運算指令后的條件轉(zhuǎn)移指令進行測試,以改變程序的流程。因而掌握指令執(zhí)行結(jié)果對標(biāo)志的影響,對編程有著重要的意義。

以下詳細介紹常用二進制數(shù)運算指令的指令格式和功能。

1.加/減法指令

指令格式:

ADDdest,src ;dest?←?(dest)+(src)

SUBdest,src ;dest?←?(dest)?-?(src)

功能:完成兩個操作數(shù)的加減運算,結(jié)果返回目標(biāo)操作數(shù)。指令的執(zhí)行結(jié)果影響所有的狀態(tài)標(biāo)志。

在使用ADD/SUB指令時,應(yīng)注意:

(1)源操作數(shù)和目標(biāo)操作數(shù)應(yīng)同時為帶符號數(shù)或同時為無符號數(shù),且二者長度應(yīng)相同。

(2)源操作數(shù)可以是通用寄存器、存儲器或立即數(shù),而目的操作數(shù)只能是通用寄存器或存儲器,不能是立即數(shù),且兩者不能同時為存儲器操作數(shù)。

參與加/減法的數(shù)據(jù)可根據(jù)程序的要求被約定為帶符號數(shù)和不帶符號數(shù):用OF表示帶符號數(shù)運算結(jié)果的溢出,而用CF表示無符號數(shù)運算結(jié)果的溢出。2.帶進位、借位的加/減法指令

指令格式:

ADCdest,src ;dest?←?(dest)+(src)+(CF)

SBB

dest,src ;dest?←?(dest)?-?(src)?-?(CF)

功能:完成兩個操作數(shù)的帶進位的加減運算,結(jié)果返回目標(biāo)操作數(shù)。該指令常用于多字節(jié)(即長度為兩個或兩個以上字)數(shù)據(jù)的加減法運算。指令的執(zhí)行結(jié)果影響所有的狀態(tài)標(biāo)志。

3.加“1”、減“1”指令

指令格式:

INCdest ;dest?←?(dest)+1

DECdest ;dest?←?(dest)-1

功能:指令I(lǐng)NC/DEC完成對指定操作數(shù)的加/減1,并將結(jié)果返回目標(biāo)操作數(shù)。

目的操作數(shù)可以是任意一個8位或16位通用寄存器或存儲單元,但不能是立即數(shù),且把操作數(shù)看作是無符號二進制數(shù)。指令執(zhí)行的結(jié)果將影響PF、AF、ZF、SF和OF,但不影響CF。

指令I(lǐng)NC/DEC常用于循環(huán)程序中循環(huán)計數(shù)器的計數(shù)值或修改地址指針。

例如:

INCSI ;修改地址指針

INCBYTEPTR[BX] ;修改地址指針

DECCX ;修改循環(huán)計數(shù)器的計數(shù)值

DECWORDPTR[BP][DI] ;修改地址指針

【例3-3】要求兩個多字節(jié)十六進制數(shù)之和:3B74AC25610FH+5B249678E345H=?假設(shè),已將被加數(shù)和加數(shù)分別存入以DATA1、DATA2為首地址的內(nèi)存區(qū)。要求相加結(jié)果送到以DATA1為首地址的內(nèi)存區(qū)。程序段如下:

MOV CX,6

MOV SI,0

CLC

LOOPER:MOV AL,DATA2[SI]

ADCDATA1[SI],AL

INCSI

DECCX

JNZLOOPER

HLT

4.求補指令

指令格式:

NEGdest ;dest?←?0-(dest)

功能:對操作數(shù)求補。該指令執(zhí)行的效果是改變操作數(shù)的符號——將正數(shù)變?yōu)樨摂?shù)或?qū)⒇摂?shù)變?yōu)檎龜?shù),但絕對值不變。由于機器中帶符號數(shù)是用補碼表示的,所以,求一個操作數(shù)的負數(shù),就是求其補碼。因此,NEG指令也叫取負指令。

注意:NEG指令是對帶符號數(shù)進行操作的;NEG指令影響所有標(biāo)志位。

【例3-4】內(nèi)存數(shù)據(jù)段存放了100個帶符號數(shù),首地址為AREA1,要求將各數(shù)取絕對值后存入以AREA2為首地址的內(nèi)存區(qū)。

問題分析:由于這100個數(shù)為帶符號數(shù),因此,先要判斷正負。若為正數(shù),可直接送至AREA2中;若為負數(shù),則需先求該負數(shù)的絕對值,然后再送至AREA2中。程序段如下:

?LEA SI,AREA1 ;SI源地址指針

?LEA DI,AREA2 ;DI目的地址指針

?MOV CX,100 ;CX循環(huán)次數(shù)

5.比較指令

指令格式:

CMPdest,src ;(src)-(dest)

功能:比較兩個數(shù)之間的大小,但運算結(jié)果不返回目標(biāo)操作數(shù),而只將比較結(jié)果反映在狀態(tài)標(biāo)志上。具體指令如下:

CMPreg,reg/mem ;例如:CMPCX,DI

CMPreg/mem,imm ;例如:CMPBUFFER,150

CMPmem,reg ;例如:CMP[BX+5],SI

在程序中,比較指令CMP常用于條件轉(zhuǎn)移指令之前,為程序是否轉(zhuǎn)移提供判決依據(jù):

(1)比較兩個數(shù)是否相等:若(ZF)?=?0,則兩數(shù)相等;否則,需利用其他標(biāo)志來判斷兩數(shù)的大小。

(2)在無符號數(shù)之間的比較中,可根據(jù)CF的狀態(tài)來判斷:

若(CF)?=?1,則(dest)?<?(src);否則,(dest)?>?(src)。

(3)在帶符號數(shù)之間的比較中,應(yīng)依據(jù)OF和CF的關(guān)系來判斷:若(OF)(CF)?=?1,則(dest)?<?(src);否則,(dest)?>?(src)?!纠?-5】在數(shù)據(jù)段從DATA開始的存儲單元中分別放了兩個8位的無符號數(shù)。試比較它們的大小,并將較大者送到MAX單元。程序段如下:

LEABX,DATA ;DATA偏移地址送BX,設(shè)置表格指針

MOVAL,[BX] ;取第一個無符號數(shù),送AL

INCBX ;BX指針指向第二個無符號數(shù)

CMPAL,[BX] ;兩個數(shù)比較

JNCDONE ;若第一個數(shù)大于第二個數(shù),即(CF)?=?0,則轉(zhuǎn)向DONE

MOVAL,[BX];否則,第二個無符號數(shù)送至AL(中間寄存器)

DONE:MOVMAX,AL

;較大的無符號數(shù)送至MAX單元

HLT

;停止

6.乘法指令

指令格式:

MULsrc

;AX?←?(src)×?(AL) (字節(jié)乘法)

;DX:AX?←?(src)×?(AX) (字乘法)

IMULsrc;與MUL指令格式相同

功能:指令MUL和IMUL分別用于無符號數(shù)的乘法和帶符號數(shù)的乘法運算。它們都只有一個源操作數(shù),而目標(biāo)操作數(shù)是隱含規(guī)定的:8位乘法時隱含的操作數(shù)為AL;16位乘法時隱含的操作數(shù)為AX。

在使用乘法指令MUL/IMUL時,應(yīng)注意:

(1)指令MUL對標(biāo)志位CF、OF有影響,而對SF、ZF、AF、PF不確定。如果運算結(jié)果的高半部分(在AH或DX中)為零,則CF?=?OF?=?0,表示在AH或DX中所存的結(jié)果為有效數(shù)字;否則CF?=?OF?=?1,表示在AH或DX中結(jié)果為無效數(shù)字。

(2)指令I(lǐng)MUL對標(biāo)志位的影響與MUL類似。由于指令I(lǐng)MUL將兩個操作數(shù)按帶符號數(shù)進行處理,如果乘積的高半部分僅是低半部分符號位的擴展,則CF?=?OF?=?0;否則,AH或DX的內(nèi)容為乘積的有效數(shù)字,這時,CF?=?OF?=?1。

例如:

MOVAX,04E8H

;(AX)=04E8H

MOVBX,4E20H ;(BX)=4E20H

IMULBX ;(DX:AX)=(AX)×(BX)

指令的執(zhí)行結(jié)果為:(DX)?=?017FH,(AX)?=?4D00H,(CF)?=?(OF)?=?1,表明DX中包含著乘積的有效數(shù)字。7.除法指令

指令格式:

(字節(jié)除法)

功能:指令DIV和IDIV分別用于無符號數(shù)的除法和帶符號數(shù)的除法運算。它們都只有一個源操作數(shù),而目標(biāo)操作數(shù)是隱含規(guī)定的:若除數(shù)為16位,則隱含的操作數(shù)為AX,其中,8位商放在AL中,8位余數(shù)放在AH中;若被除數(shù)為32位,則隱含的操作數(shù)為DX:AX,其中,16位商放在AX中,16位余數(shù)放在DX中。

在使用除法指令DIV/IDIV時,應(yīng)注意:

(1)指令DIV/IDIV使?fàn)顟B(tài)標(biāo)志位(如SF、ZF、AF、PF、CF和OF)的值不確定。

(2)除法指令中被除數(shù)的長度應(yīng)為除數(shù)長度的兩倍。如果被除數(shù)長度和除數(shù)長度相等,則應(yīng)在使用除法指令之前,將被除數(shù)的高位進行擴展——用DIV指令時,高位擴展為8或16個零;用IDIV指令時,用專門的符號擴展指令CBW或CWD,對被除數(shù)的符號位進行擴展。

(3)除法的溢出問題:①在執(zhí)行DIV指令時,如果除數(shù)為零,或AL(AX)中的商大于FFH(FFFFH)時,則CPU立即自動產(chǎn)生一個類型號為0的內(nèi)部中斷(除法出錯中斷),且商和余數(shù)為不確定值。②在執(zhí)行IDIV指令時,如果商的范圍超過了?-127~+127(字節(jié)除法時)或?-32?767~+32?767(字除法時),也會產(chǎn)生與DIV指令相同的溢出問題。

8.符號擴展指令

指令格式1:

CBW

;如果(AL)<80H,AH?←?00H;否則,AH?←?0FFH

指令格式2:

CWD

;如果(AX)<8000H,DX?←?0000H;否則,DX?←?0FFFFH

功能:CBW和CWD分別將帶符號數(shù)按其符號從字節(jié)擴展成字或?qū)⒆謹U展成雙字,且操作數(shù)隱含在累加器中。該類指令對狀態(tài)標(biāo)志均無影響。

【例3-6】編程完成0BF4H÷0123H(帶符號數(shù)相除)運算。

問題分析:由于除數(shù)為帶符號的字,則必須將原來的除數(shù)進行符號擴展后才能相除。程序如下:

MOVAX,0BF4H

CWD ;被除數(shù)擴展為(DX:AX)=00000BF4H

MOVBX,123H

IDIVBX ;(AX)=00BH(商),(DX)=F4H(余數(shù))

應(yīng)注意,對于無符號數(shù),無須用CBW或CWD指令,而只須簡單地在無符號數(shù)的高半段補零即可。3.2.3位操作類指令

1.邏輯運算指令

邏輯運算指令可對字節(jié)或字操作數(shù)按位進行邏輯運算。源和目標(biāo)操作數(shù)可以是通用寄存器或存儲器,但兩者不能均是存儲器;源操作數(shù)可以使用立即數(shù),但目的操作數(shù)卻不能。

應(yīng)注意,段寄存器不能作為源或目的操作數(shù)。邏輯運算指令如表3-3所示。

NOT指令對標(biāo)志寄存器各位均無影響,而其他4條指令對標(biāo)志寄存器有影響:SF、ZFPF根據(jù)運算結(jié)果設(shè)置相應(yīng)位,CF、OF總是置“0”,AF不確定。

1)邏輯“與”指令A(yù)ND

指令格式:

ANDdest,src ;dest?←?(dest)∩(src)

功能:將目標(biāo)操作數(shù)和源操作數(shù)按位進行邏輯“與”運算,并將運算結(jié)果送回目標(biāo)操作數(shù)。AND指令可用來:①屏蔽運算結(jié)果中的某些位,而保留其他有用的位;②對狀態(tài)標(biāo)志位產(chǎn)生影響。如果將某個操作數(shù)自己與自己相“與”,雖然操作數(shù)內(nèi)容不變,但該操作卻影響了SF、ZF和PF狀態(tài)標(biāo)志位,且將OF和CF清零。

【例3-7】將數(shù)字“6”的ASCII碼轉(zhuǎn)換成相應(yīng)的非壓縮BCD碼。程序如下:

MOVAL,‘6’

;?(AL)=00110110B=36H

ANDAL,0FH ;?(AL)=00000110B(屏蔽第4~7位)

【例3-8】

由于數(shù)據(jù)傳送類指令不會對狀態(tài)標(biāo)志位產(chǎn)生影響,因而,若在該類指令后加一條AND指令,就可以實現(xiàn)條件判斷和程序轉(zhuǎn)移。程序如下:

AND

AX,AX;影響標(biāo)志,但AX內(nèi)容不變,即(AX)=DATA

JZ

NEXT

;如(AX)=0,轉(zhuǎn)移到NEXT;否則,順序執(zhí)行

NEXT:

2)邏輯“或”指令OR

指令格式:

ANDdest,src ;dest?←?(dest)∪(src)

功能:將目標(biāo)操作數(shù)和源操作數(shù)按位進行邏輯“或”運算,并將運算結(jié)果送回目標(biāo)操作數(shù)。OR指令常用于以下幾種情況:

(1)將寄存器或存儲器中某些特定位置“1”,同時使其他位保持原來的狀態(tài);

(2)對狀態(tài)標(biāo)志位產(chǎn)生影響?!纠?-9】將AH、AL寄存器的最高位置“1”。程序如下:

MOVAX,3663H ;(AX)=0011011001100011B

ORAX,8080H ;(AH)=10110110B,(AL)=11100011B

(3)有時,OR指令的作用與加法指令A(yù)DD的作用相似。

例如:

MOVAL,00000110B ;(AL)=數(shù)字“6”

ORAL,30H

;(AL)=36H(數(shù)字“6”的ASCII碼)

3)邏輯“異或”指令XOR

指令格式:

XORdest,src ;dest?←?(dest)

(src)

功能:將目標(biāo)操作數(shù)和源操作數(shù)按位進行邏輯“異或”運算,并將運算結(jié)果送回目標(biāo)操作數(shù)。XOR指令常用于:

(1)將寄存器或存儲器中某些特定位取“反”,同時使其他位保持原來的狀態(tài);

(2)將寄存器的內(nèi)容清零。

【例3-10】將AL寄存器中的第1、3、5、7位取“反”。程序如下:

MOVAL,0FH

;(AL)=00001111B

XORAL,0AAH;(AL)=10100110B,與指令MOVAX,0或SUBAX,AX同

4)邏輯“非”指令NOT

指令格式:

NOTdest ;dest?←?0FFFFH?-?(dest)(字取反)

功能:將源操作數(shù)按位進行“非”(即取反)運算,并將結(jié)果送回目標(biāo)操作數(shù)。

應(yīng)注意,NOT指令的操作數(shù)可以是8(或16)位的寄存器或存儲器,不能是一個立即數(shù)。

【例3-11】將存儲器[AL]的內(nèi)容取“反”。程序如下:

MOV[AL],01011011B;[AL]=01011011B=5CH

NOT[AL] ;[AL]=10100100B=0A4H

5)測試指令TEST

指令格式:

TESTdest,src ;(dest)∩(src)

功能:將目標(biāo)操作數(shù)和源操作數(shù)按位進行邏輯“與”運算,但運算結(jié)果不送回目標(biāo)操作數(shù)。指令TEST的主要作用是進行位測試。

其可與條件轉(zhuǎn)移指令一起,共同完成對某個(些)特定位狀態(tài)的判斷,并實現(xiàn)相應(yīng)的程序轉(zhuǎn)移。這種作用與CMP相類似,只不過TEST指令只比較某一特定的位,而CMP指令卻比較整個操作數(shù)。

【例3-12】已知某外設(shè)的一個端口地址為PORT,若該外設(shè)端口輸入數(shù)據(jù)的第1、3、5位中的任何一位不為零,則轉(zhuǎn)移到NEXT。程序如下:

INAL,PORT

TEST?AL,00101010B ;測試第1、3、5位

JNZNEXT ;若第1、3、5位中有一位不為零,則轉(zhuǎn)移到NEXT

NEXT:

再者,一個邏輯表達式一般是由“與”、“或”、“異或”、“非”這四個基本邏輯運算構(gòu)成的。因此,經(jīng)過邏輯表達式的演算變化后所編制的程序就可以實現(xiàn)復(fù)雜的邏輯運算。

2.移位/循環(huán)移位類指令

這組指令可以對8位或16位的寄存器或存儲器中的各位進行邏輯移位、算術(shù)移位或循環(huán)移位。指令及其對應(yīng)的操作功能如表3-4所示。

指令中的count為計數(shù)值,其決定了移位或循環(huán)移位的次數(shù)。計數(shù)值可以是1,或者是CL中的內(nèi)容所規(guī)定的次數(shù)。實際應(yīng)用中,一般選用0~15,其中,“0”表示不移位;另外,移位指令都影響標(biāo)志位,但影響的方式各指令不盡相同。

1)移位指令

指令格式:

SHL/SAL/SHR/SARreg,1或CL移位指令影響狀態(tài)標(biāo)志位PF、SF、ZF、CF以及OF,但對AF的影響不定。其中,CF總是等于目標(biāo)操作數(shù)最后移出的那一位。如果移位計數(shù)值為1,且執(zhí)行結(jié)果使目標(biāo)操作數(shù)的符號位M(即最高位)發(fā)生了變化,則(OF)?=?1;否則,(OF)?=?0。若移位計數(shù)值大于1,則OF狀態(tài)不確定。指令操作如圖3-1所示。

移位指令常用來實現(xiàn)對二進制數(shù)進行2的方冪運算,或用來將字節(jié)或字的某些位分離出來,還可以對寄存器或存儲器中的任何一位進行測試(此時,先將待測位移至CF中,然后測試CF位)。

圖3-1移位指令操作

【例3-13】將一個16位無符號數(shù)乘以10。該數(shù)原來存放在以FAT為首地址的兩個連續(xù)的存儲單元中。

問題分析:由于FAT?×?10?=?(8?×?FAT)?+?(2?×?FAT)?=?(23?×?FAT)?+?(2?×?FAT),故可以用左移指令來實現(xiàn)。程序如下:

【例3-14】若AH、AL中分別存放有非壓縮BCD碼,要求將它們轉(zhuǎn)換成壓縮的BCD碼,并存于AL中。完成此功能的程序段如下:

MOV

CL,4 或:

MOV CL,4

SHL

AL,CL SHL AH,CL

SHR AX,CL ADD AL,AH

2)循環(huán)移位指令

指令格式:

ROL/ROR/RCL/RCRreg或mem,1或CL循環(huán)移位分大循環(huán)(帶進位標(biāo)志CF循環(huán)移位)和小循環(huán)(不帶進位標(biāo)志CF循環(huán)移位)兩種。循環(huán)移位指令只影響CF和OF兩個標(biāo)志。其中,CF總是等于目標(biāo)操作數(shù)最后一次循環(huán)移出的那一位,而OF標(biāo)志的變化規(guī)則與移位指令的OF變化規(guī)則相同。循環(huán)指令操作如圖3-2所示。

應(yīng)注意到,循環(huán)移位指令與移位指令有所不同。循環(huán)移位操作后,操作數(shù)中原來各位的信息并未丟失,只是移到了操作數(shù)中的其他位或進位標(biāo)志上,必要時還可以恢復(fù)。

圖3-2循環(huán)移位指令操作

【例3-15】要求完成一個32位數(shù)乘4。由于8086?CPU指令集中沒有32位數(shù)的運算指令,所以,在此可用兩個寄存器DX:AX來表示32位數(shù)。程序如下:3.2.4串操作類指令

8088/8086?CPU指令系統(tǒng)中有一組十分有用的串操作指令,這組指令的操作對象不只是單個的字節(jié)或字,而是內(nèi)存中地址連續(xù)的字節(jié)串或字串。每次經(jīng)過基本操作后,指令能夠自動修改地址,為下一次操作做好準(zhǔn)備。串操作指令可處理的數(shù)據(jù)串的最大長度為64?KB。

串操作指令共有以下五條:串傳送指令(MOVS)、串裝入指令(LODS)、串送存指令(STOS)、串比較指令(CMPS)和串掃描指令(SCAS),如表3-5所示。

串操作指令還可以加上重復(fù)前綴。此時,指令規(guī)定的操作將一直重復(fù)下去,直到完成預(yù)定的重復(fù)操作次數(shù)。串操作指令的重復(fù)前綴、操作數(shù)以及地址指針?biāo)玫募拇嫫鞯惹闆r如表3-6所示。

1.重復(fù)前綴

重復(fù)前綴REP/REPE/REPNE/REPZ/REPNZ是用來控制其后的基本串操作指令是否重復(fù),重復(fù)前綴不能單獨使用。

有的串操作指令(如MOVS、LODS、STOS)可加重復(fù)前綴REP,這時,指令規(guī)定的操作可重復(fù)進行,重復(fù)操作的次數(shù)由約定的CX寄存器的內(nèi)容決定。CPU按以下步驟執(zhí)行:

①首先檢查CX寄存器,若(CX)?=?0,則退出REP操作;

②指令執(zhí)行一次字符串基本操作;

③根據(jù)DF標(biāo)志修改地址指針;

④CX減1(但不改變標(biāo)志);

⑤重復(fù)①~④。

若串操作指令如CMPS、SCAS的基本操作影響零標(biāo)志ZF,則可加重復(fù)前綴REPE/REPZ或REPNE/REPNZ。此時,串操作重復(fù)進行的條件為(CX)?≠?0;同時,還要求ZF的值滿足重復(fù)前綴中的規(guī)定:REPE/REPZ要求(ZF)?=?1,

REPNE/REPNZ要求(ZF)?=?0。

串操作匯編指令的格式可以寫上操作數(shù),也可以只在指令助記符后加上字母“B”(字節(jié)操作)或“W”(字操作)。加上字母“B”或“W”后,指令助記符后面不需要,也不允許再寫操作數(shù)了。

2.基本串操作指令

1)串傳送指令

指令格式:

[REP]MOVS [ES:]dest_string,[sreg:]src_string

[REP]MOVSB ;字節(jié)串傳送

[REP]MOVSW ;字串傳送

指令功能:將DS:SI指定的源串中的一個字節(jié)或字,傳送到由ES:DI指定的目標(biāo)串中,且根據(jù)方向標(biāo)志DF自動地修改SI、DI,以指向下一個元素。其執(zhí)行的操作為:

①ES

:DI?←?(DS:SI)

②SI?←?(SI)?±?1,DI?←?(DI)?±?1 (字節(jié)操作)

SI?←?(SI)?±?2,DI?←?(DI)?±?2 (字操作)

其中,當(dāng)方向標(biāo)志(DF)=0時用“+”,當(dāng)方向標(biāo)志(DF)?=?1時用“-”。

以上各種格式中,凡是方括號中的內(nèi)容均表示任選項。串傳送指令不影響狀態(tài)標(biāo)志位。

在第1種格式中,串操作指令給出了源操作數(shù)和目標(biāo)操作數(shù),此時,指令執(zhí)行字節(jié)操作還是字操作,取決于這兩個操作數(shù)定義時的類型。給出源操作數(shù)和目標(biāo)操作數(shù)的作用有兩個:①用以說明操作對象的大小(字節(jié)或字);②明確指出所涉及到的段寄存器(sreg),而指令執(zhí)行時,仍用SI和DI寄存器尋址操作數(shù)。必要時可以用類型運算符PTR說明操作對象的類型。

第1種格式的一個優(yōu)點是可以對源字符串進行段重設(shè)(但應(yīng)注意,目的字符串的段基址只能在ES,且不可進行段重設(shè))。

在第2和第3種格式中,串操作指令字符的后面加上一個字母“B”或“W”,用以指出操作對象是字節(jié)串或字串。此時,指令后面不需要出現(xiàn)操作數(shù)。以下指令都是合法的:

REPMOVSDATA2,DATA1 ;應(yīng)預(yù)先定義操作數(shù)類型

MOVSBUFFER2,ES:BUFFER1;源操作數(shù)進行段重設(shè)

REPMOVSWORDPTR[DI],[SI];用變址寄存器表示操作數(shù)

REPMOVSB ;字節(jié)串傳送

?MOVSW ;字串傳送

串操作指令常與重復(fù)前綴聯(lián)合使用,這樣不僅可以簡化程序,而且提高了程序運行的速度。

【例3-16】將數(shù)據(jù)段中首地址為BUFFER1的200個字節(jié)數(shù)據(jù)傳送到附加段首地址為BUFFER2的內(nèi)存區(qū)中。使用字節(jié)串傳送指令的程序段如下:

LEASI,BUFFER1 ;SI?←?源串首地址指針

LEADI,BUFFER2 ;DI?←?目的串首地址指針

MOVCX,200 ;CX?←

字節(jié)串長度

CLD ;清方向標(biāo)志DF

HLT ;停止

2)串裝入指令LODS

指令格式:

LODS [sreg:]src_string

LODSB ;字節(jié)串裝入

LODSW ;字串裝入

指令功能:將DS:SI指定的源串中的字節(jié)或字逐個裝入累加器AL或AX中,同時,自動修改SI。指令的基本操作為:

AL

←?(DS:SI))

AX

←?(DS:SI)

②SI

←?(SI)?±?1(字節(jié)操作)

SI?←?(SI)?±?2(字操作)

其中,當(dāng)方向標(biāo)志(DF)=0時用加號“+”,當(dāng)方向標(biāo)志(DF)=1時用減號“-”。

LODS指令不影響狀態(tài)標(biāo)志位,而且一般不帶重復(fù)前綴。因為,將字符串的每個元素重復(fù)地裝入到累加器中沒有實際意義。

3)串送存指令STOS

指令格式:

[REP]STOSB ;字節(jié)串送存

STOSW ;字串送存

指令功能:將累加器AL或AX的內(nèi)容送存到內(nèi)存緩沖區(qū)中由ES:DI指定的目標(biāo)串中,同時,自動修改DI。指令的基本操作為:

ES:DI?←?(AL)

ES:DI?←?(AX)

DI

←?(DI)?±?1 (字節(jié)操作)

DI?←(DI)?±?2 (字操作)

其中,當(dāng)方向標(biāo)志(DF)?=?0時用加號“+”,當(dāng)方向標(biāo)志(DF)?=?1時用減號“-”。

STOS指令對狀態(tài)標(biāo)志位沒有影響。指令若加上重復(fù)前綴REP,則操作將一直重復(fù)進行下去,直到(CX)?=?0。

【例3-17】將字符“#”裝入以AREA為首址的100個字節(jié)的內(nèi)存空間中。

LEA??DI,AREA

MOVAX,‘##’

MOVCX,50

CLD

REPSTOSW

HLT

程序說明:以上程序采用了送存50個字而不是送存100個字節(jié)的方法,雖然這兩種方法程序執(zhí)行的結(jié)果是相同的,但以上程序的執(zhí)行速度更快些。

4)串比較指令

指令格式:

[REPE/REPNE]CMPSB ;字節(jié)串比較

CMPSW ;字串比較

指令功能:將由DS:SI指定的源串中的元素與由ES:DI指定的目標(biāo)串中的元素逐個比較(即相減),但比較結(jié)果不送回目標(biāo)操作數(shù),僅反映在狀態(tài)標(biāo)志位上。CMPS指令對狀態(tài)標(biāo)志位SF、ZF、AF、PF、CF和OF有影響。

串比較指令的基本操作為:

①(DS

:SI)-(ES:DI)

②SI?←?(SI)?±?1,DI?←?(DI)?±?1(字節(jié)操作)

SI?←?(SI)?±?2,DI?←?(DI)?±?2(字操作)

其中,當(dāng)方向標(biāo)志(DF)=0時用加號“+”,當(dāng)方向標(biāo)志(DF)?=?1時用減號“-”。

CMPS指令中的源操作數(shù)在前,而目標(biāo)操作數(shù)在后;另外,CMPS指令可以加重復(fù)前綴REPE(或?qū)懗蒖EPZ)或REPNE(或?qū)懗蒖EPNZ),這是由于CMPS指令影響著標(biāo)志ZF。

如果兩個被比較的字節(jié)或字相等,則(ZF)?=?1;否則,(ZF)?=?0。

REPE或REPZ表示:當(dāng)(CX)

0,且(ZF)?=?1時,繼續(xù)進行比較。

REPNE或REPNZ表示:當(dāng)(CX)

0,且(ZF)=0時,繼續(xù)進行比較。

【例3-18】比較兩個字符串,找出其中第一個不相等字符的地址。如果兩個字符全部相同,則轉(zhuǎn)到ALLMATCH進行處理。這兩個字符串長度均為20,首地址分別為STRING1和STRING2。程序說明:在上述程序段中使用重復(fù)前綴REPE或REPZ,當(dāng)遇到第一個不相等的字符時,停止比較。但此地址已被修改,即(DS:SI)和(ES:DI)均已經(jīng)指向下一個字節(jié)或字地址,應(yīng)將SI和DI進行修正,使之指向所要尋找的不相等字符。但是,也有可能將整個字符串比較完畢后仍未出現(xiàn)規(guī)定的條件(如兩個字符相等或不相等),但此時寄存器(CX)=0,故可用條件轉(zhuǎn)移指令JCXZ進行處理;同理,如果要尋找兩個字符串中第一個相等的字符,則應(yīng)使用重復(fù)前綴REPNE或REPNZ。

5)串掃描指令

指令格式:

[REPE/REPNE]?SCASB ;搜索字節(jié)串

SCASW

;搜索字串

串掃描指令的基本操作為:

(AL)-(ES:DI)

?(AX)-(ES:DI)

DI?←?(DI)?±?1(字節(jié)操作)

DI?←?(DI)?±?2(字操作)

其中,當(dāng)方向標(biāo)志(DF)?=?0時用加號“+”,當(dāng)方向標(biāo)志(DF)?=?1時用減號“-”。

SCAS指令將累加器的內(nèi)容與字符串中的元素逐個進行比較,比較結(jié)果也反映在狀態(tài)標(biāo)志位上。SCAS指令將影響狀態(tài)標(biāo)志位SF、ZF、AF、PF、CF和OF。如果累加器的內(nèi)容與字符串中的元素相等,則比較之后,(ZF)?=?1。因此,指令可以加上重復(fù)前綴REPE或REPNE。

【例3-19】在某一數(shù)據(jù)塊中搜索尋找一個關(guān)鍵字。找到該字后,把搜索次數(shù)記錄在COUNT單元中,并將關(guān)鍵字的地址保留在ADDR中,然后,在屏幕上顯示字符“Y”。如果沒有找到關(guān)鍵字,則在屏幕上顯示字符“N”。

綜上所述,雖然串操作指令的基本操作各不相同,但都具有以下共同特點:

(1)都是用SI尋址源操作數(shù),用DI尋址目標(biāo)操作數(shù),且源操作數(shù)常用在當(dāng)前的數(shù)據(jù)段,即隱含段寄存器DS(允許段超越),而目標(biāo)操作數(shù)總是在當(dāng)前的附加段,隱含段寄存器ES(不允許段超越)。

(2)用方向標(biāo)志DF規(guī)定進行串處理的方向。當(dāng)(DF)?=?0時,地址指針增量;當(dāng)(DF)?=?1時,地址指針減量。有的串操作指令可加重復(fù)前綴,以完成對數(shù)據(jù)串的重復(fù)操作。這種方法使得處理長數(shù)據(jù)串比用軟件循環(huán)方法進行處理快的多,但這時必須用CX作為重復(fù)次數(shù)計數(shù)器。每執(zhí)行一次串操作指令,CX值自動減1,直至為0,停止串操作。3.2.5控制轉(zhuǎn)移類指令

轉(zhuǎn)移控制類指令用于控制程序的流程。這類指令包括:無條件轉(zhuǎn)移指令、條件轉(zhuǎn)移指令、循環(huán)控制指令、過程調(diào)用指令和中斷指令。該類指令的共同特點是修改IP,或同時修改IP和CS的內(nèi)容,以改變程序的正常執(zhí)行順序,使之轉(zhuǎn)移到新的目標(biāo)地址去繼續(xù)執(zhí)行。上述五類指令中,除中斷指令以外,其他轉(zhuǎn)移指令都不影響狀態(tài)標(biāo)志位。

如果轉(zhuǎn)移的目標(biāo)地址在當(dāng)前代碼段內(nèi),則目標(biāo)屬性為NEAR,稱為段內(nèi)轉(zhuǎn)移,這時,指令只修改IP;如果轉(zhuǎn)移的目標(biāo)地址在其他代碼段內(nèi),則目標(biāo)屬性為FAR,稱為段間轉(zhuǎn)移,這時,指令同時修改IP和CS。

1.無條件轉(zhuǎn)移指令JMP

無條件地控制程序轉(zhuǎn)移到指令中操作數(shù)oprd所指定的目標(biāo)地址。目標(biāo)地址可以用直接的方式給出,也可以用間接的方式給出。無條件轉(zhuǎn)移指令對狀態(tài)標(biāo)志位沒有影響。

1)段內(nèi)直接轉(zhuǎn)移

指令格式:

JMPNEARPTRlabel ;IP?←?(IP)+disp(16位)

功能:指令的操作數(shù)是一個近標(biāo)號,該標(biāo)號在本段(或本組)內(nèi)。指令匯編以后,可計算出JMP指令的下一條指令的地址到目標(biāo)地址之間的16位相對偏位移量disp16。因而,段內(nèi)直接轉(zhuǎn)移也稱“近轉(zhuǎn)移”,屬于相對轉(zhuǎn)移。

2)段內(nèi)直接短轉(zhuǎn)移

指令格式:

JMPSHORTlabel ;IP?←?(IP)+disp(8位)

功能:將程序無條件地轉(zhuǎn)移到目標(biāo)地址label。段內(nèi)直接短轉(zhuǎn)移指令的操作數(shù)是一個短標(biāo)號。該種轉(zhuǎn)移也屬于相對轉(zhuǎn)移,相對偏移量disp的范圍在?-128~127字節(jié)之間。如果已知下一條指令到目的地址之間的相對位移量在

-128~127字節(jié)的范圍內(nèi),則可在標(biāo)號前寫上運算符SHORT,以實現(xiàn)段內(nèi)直接短轉(zhuǎn)移。

3)段內(nèi)間接轉(zhuǎn)移

指令格式:

JMPreg16/mem16 ;IP?←?(reg16)/[mem16]

功能:使程序無條件地轉(zhuǎn)移到由寄存器的內(nèi)容所指定的目標(biāo)地址,或無條件地轉(zhuǎn)移到由各種存儲器尋址方式提供的存儲單元內(nèi)容所指定的目標(biāo)地址。段內(nèi)間接轉(zhuǎn)移屬于絕對轉(zhuǎn)移。由于是段內(nèi)轉(zhuǎn)移,故只修改當(dāng)前IP值,而段寄存器CS的內(nèi)容保持不變。例如:

MOVBX,1000H

JMPBX ;程序?qū)⒅苯愚D(zhuǎn)向1000H,即IP?←?1000H

JMPWORDPTR[BX+20H]

;將存儲器操作數(shù)定義為WORD(即16位字)

在上述程序段中,假設(shè)?(DS)?=?2000H,[21020H]?=?34H,[21021H]?=?12H,則第2個JMP指令將使程序轉(zhuǎn)向1234H,即(IP)?=?1234H。

4)段間直接轉(zhuǎn)移

指令格式:

JMPFARPTRlabel ;IP?←?label偏移地址,CS?←?label段基址

功能:使程序無條件地轉(zhuǎn)移到指定段的段內(nèi)目標(biāo)地址label。指令的操作數(shù)是一個遠標(biāo)號,該標(biāo)號在另一個代碼段內(nèi)。該指令也屬于絕對轉(zhuǎn)移指令。指令的操作是將標(biāo)號的偏移地址取代當(dāng)前IP指令指針的內(nèi)容;同時,將標(biāo)號的段基址取代當(dāng)前段寄存器CS的內(nèi)容,最終,控制程序轉(zhuǎn)移到另一代碼段內(nèi)指定的標(biāo)號處。

5)段間間接轉(zhuǎn)移

指令格式:

JMPmem32 ;IP?←?[mem32],

CS?←?[mem32+2]

功能:使程序無條件地轉(zhuǎn)移到由mem32所指定的另一個代碼段中。存儲器的前兩個字節(jié)的內(nèi)容為IP,后兩個字節(jié)的內(nèi)容為CS的目標(biāo)地址。該轉(zhuǎn)移屬于絕對轉(zhuǎn)移。

例如:

MOVSI,0100H

JMPDWORDPTR[SI] ;將存儲器操作數(shù)的類型定義為DWORD(雙字,即32位)

這段程序執(zhí)行完畢后,將DS:[SI],即DS:0100H和DS:0101H兩個單元的內(nèi)容送至IP;而把DS:[SI+2],即DS:0102H和DS:0103H兩個單元的內(nèi)容送至CS。由此,程序轉(zhuǎn)入由新的CS和新的IP決定的目標(biāo)地址。

2.條件轉(zhuǎn)移指令

歸納起來,條件轉(zhuǎn)移指令可分為四類,如表3-7所示。

條件轉(zhuǎn)移指令的執(zhí)行包括兩個過程:第一步,測試規(guī)定的條件。第二步,如果條件滿足,則程序轉(zhuǎn)移到指定的目標(biāo)標(biāo)號oprd處;否則,繼續(xù)順序執(zhí)行。

由于條件轉(zhuǎn)移指令對狀態(tài)標(biāo)志位沒有影響,因此在程序中,條件轉(zhuǎn)移指令一般都跟在算術(shù)運算或邏輯運算指令之后,通過檢測運算結(jié)果所設(shè)置的一個標(biāo)志位的狀態(tài),或綜合檢測幾個標(biāo)志位的狀態(tài)來判斷轉(zhuǎn)移條件是否滿足。

3)用于帶符號數(shù)比較的條件轉(zhuǎn)移指令

該類指令適用于根據(jù)帶符號數(shù)之間的比較結(jié)果來決定是否轉(zhuǎn)移的場合。指令在執(zhí)行時所檢測的是帶符號數(shù)比較結(jié)果的特征標(biāo)志SF、OF和ZF。

【例3-21】有兩個數(shù)(AL)?=?01H和(BL)?=?FEH,若它們作為無符號數(shù),則01H小于FEH;但作為帶符號數(shù),01H則大于FEH(-2D)。當(dāng)指令CMPAL,BL執(zhí)行后,(AL)?=?01H,(CF)?=?1,(OF)?=?0,(ZF)?=?0。

指令說明:

①當(dāng)兩數(shù)均為無符號數(shù)時,若要求(AL)?>?(BL)時,程序轉(zhuǎn)移,則必須使用“高于”指令“JA”。但這時,因為(AL)?<?(BL),轉(zhuǎn)移條件(CF)?=?0,且(ZF)?=?0不滿足,所以,不會發(fā)生轉(zhuǎn)移。

②當(dāng)兩數(shù)均為帶符號數(shù)時,若要求(AL)?>?(BL)時,程序轉(zhuǎn)移,則必須使用“大于”指令“JG”。此時,由于(AL)?>?(BL)成立,滿足轉(zhuǎn)移條件(SF)(OF)?=?0,且(ZF)?=?0,所以,會發(fā)生轉(zhuǎn)移。

4)以CX的內(nèi)容為檢測條件的轉(zhuǎn)移指令JCXZ

指令格式:

JCXZOPR ;當(dāng)(CX)=0時,程序轉(zhuǎn)移至OPR

應(yīng)注意:絕大多數(shù)條件轉(zhuǎn)移指令(除JCXZ指令外)都是將狀態(tài)標(biāo)志位的狀態(tài)作為測試的條件。因此,在使用條件轉(zhuǎn)移指令時,應(yīng)首先執(zhí)行對有關(guān)標(biāo)志位有影響的指令,然后再用條件轉(zhuǎn)移指令測試這些標(biāo)志的狀態(tài),以確定程序是否轉(zhuǎn)移。例如,可利用CMP、TEST和OR指令與條件轉(zhuǎn)移指令配合使用。因為,這些指令雖不改變目標(biāo)操作數(shù)的內(nèi)容,但影響著狀態(tài)標(biāo)志位。另外,其他指令如加法、減

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論