版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第3章IBMPC匯編語言程序設(shè)計3.1基本概念
3.2Intel80x86系列CPU指令系統(tǒng)
3.3匯編語言程序設(shè)計的基本方法
3.4匯編語言程序上機過程
小結(jié)
習(xí)題三 3.1基本概念
3.1.1匯編語言與機器語言
計算機語言是人與計算機之間傳遞信息的媒介,經(jīng)歷了從機器語言、匯編語言到高級語言的發(fā)展過程。無論哪種語言,它都規(guī)定了一系列用于編寫程序的基本語句和語法規(guī)則。人們根據(jù)一種語言給定的基本語句及其語法規(guī)則可以寫出程序,計算機通過執(zhí)行已編好的程序來完成人們要求它完成的各種功能。匯編語言與高級語言的區(qū)別在于,匯編語言是與CPU緊密相關(guān)的,例如把針對Intel80x86系列CPU設(shè)計的匯編語言稱為Intel80x86匯編語言,把針對Zilog公司生產(chǎn)的Z80CPU所設(shè)計的匯編語言稱為Z80匯編語言。用Intel80x86匯編語言開發(fā)的程序在Z80CPU上是不能運行的,同樣用Z80匯編語言開發(fā)的程序,在Intel80x86CPU上也是無法運行的。高級語言則不然,我們不把C語言命名為Intel80x86C語言或Z80C語言,這是因為用C語言開發(fā)的一個程序,在各種型號的CPU上都可以正確地運行。因此,高級語言是與CPU無關(guān)的。
那么,什么是機器語言?匯編語言與機器語言之間又有什么關(guān)系呢?下面通過一個應(yīng)用實例說明機器語言和匯編語言的區(qū)別。問題:利用Intel8086CPU實現(xiàn)如下操作:在寄存器AX中加上一個常數(shù)2,在寄存器BX中減去一個常數(shù)3,把寄存器CX中的內(nèi)容傳送到寄存器DX中。
解答:針對Intel80x86CPU,解決上述問題的機器語言程序為
000001010000001000000000
100000111110101100000011
1000101111010001
針對Intel80x86CPU,解決上述問題的匯編語言程序為
ADDAX,02H
SUBBX,03H
MOVDX,CX上面兩段程序?qū)崿F(xiàn)的功能是完全相同的。顯然,用匯編語言編寫的程序比用機器語言編寫的程序更清晰、更容易閱讀和調(diào)試。
機器語言是這樣一種語言,它的每條語句就是計算機可以直接執(zhí)行的一條指令,這些指令以二進制碼的形式表示。匯編語言的每條語句則是用一種讓人容易記憶的符號表示的一條指令,這些符號必須轉(zhuǎn)換成計算機所能夠認識的二進制碼的形式即機器語言指令之后,才能夠被計算機所理解并執(zhí)行。匯編語言的基本思想是采用一組字母、數(shù)字或符號來代替一條二進制碼表示的指令,例如上面所述的指令000001010000001000000000,可采用字符ADDAX,02來代替,它表示將累加器AX中的內(nèi)容加上一個常數(shù)02。顯然,這要比一串二進制碼清晰多了,既容易書寫,也容易記憶。表示一條指令的這些字符常稱為助記符。
必須指出,采用助記符寫出的程序計算機是不能直接執(zhí)行的,因為CPU在設(shè)計時是按二進制指令碼考慮的。所以,采用匯編語言編寫的程序在執(zhí)行前還必須將其“翻譯”成機器語言。通常將采用助記符寫成的程序稱為源程序,將它翻譯生成的機器語言程序稱為目標程序。將源程序翻譯成目標程序的工作是由匯編程序來完成的。匯編語言中規(guī)定了兩種類型的指令,即指令和偽指令。每條指令由匯編程序翻譯成一組二進制代碼,對應(yīng)CPU的一個基本操作。偽指令則僅在匯編過程中告訴匯編程序如何匯編,例如告訴匯編程序已寫出的匯編語言源程序有幾個段,各段的名稱是什么,匯編到某處是否需要留出存儲空間,是否要用到外部變量等。指令與偽指令都是組成匯編語言源程序的基本語句。本章將逐步介紹這些內(nèi)容,并在此基礎(chǔ)上介紹匯編語言程序設(shè)計的基本方法。3.1.2匯編語言語句的組成
匯編語言源程序是由若干條語句組成的,語句則由標識符、操作助記符、操作數(shù)、注釋四部分組成,如下所示:
例如:
CYCLE:ADDAX,02 ;(AX)←(AX)+02
DATA1DB20H,30H,40H,50H
1.標識符
語句中的標識符是一個統(tǒng)稱(Identifier)。標識符又可以分為標號(Label)和名稱(Name)兩大類。通常把指令前的標識符稱為標號,書寫時在標號與指令之間加冒號;把定義數(shù)據(jù)(或變量)的偽指令和其它偽指令之前的標識符稱為名稱,書寫時在名稱與偽指令之間加空格。
標識符可由大小寫英文字母、數(shù)字(0~9)及特殊符號(?、·?、@、-、$)組成。標識符必須由字母打頭,若標識符中有圓點符,則圓點符必須用作第一個字符,數(shù)字不能用作第一個字符。構(gòu)成標識符的字符總數(shù)可多達31個;若超過31個字符,則31個字符以后的字符無效。語句的標識符是它后面各項所在內(nèi)存單元首地址的符號表示,稱為符號地址。標識符不是所有語句都必需的。
2.操作助記符
操作助記符是匯編語言中規(guī)定了明確含義的一組符號,指出該語句的基本功能。每條語句都必須有操作助記符,上面例中的ADD是加法指令的助記符,DB則是定義字節(jié)變量的偽指令助記符。
3.操作數(shù)
語句中的操作數(shù)部分,可以是數(shù)據(jù)本身,也可以是指出如何獲得操作數(shù)的信息。前者可以是一個常數(shù),也可以是代表常數(shù)的一個標識符或表達式;后者通常是以某種尋址方式給出的存放操作數(shù)的地址,如上例中的第一條語句中的第一個操作數(shù)部分,它指出該操作數(shù)存放在AX中,而第二個操作數(shù)部分則為參加運算的操作數(shù)本身。操作數(shù)不是每條語句所必需的。若語句為指令,那么語句中可以沒有操作數(shù),也可以有1個或2個操作數(shù),如上例中的第一條語句,具有2個操作數(shù)。若語句為偽指令,則可以有多個操作數(shù)。如上例中的第二條語句,具有4個操作數(shù)。當(dāng)語句中具有2個以上的操作數(shù)時,操作數(shù)之間用逗號“,”分隔,操作數(shù)與操作助記符之間必須以空格分隔。
4.注釋
注釋僅用作語句或程序段的說明,匯編時不形成任何目標碼。注釋部分以分號“;”開頭,表示在一行中,從“;”開始到該行末的部分不進行匯編。3.1.3常數(shù)與表達式
1.常數(shù)
常數(shù)分為數(shù)值常數(shù)和字符串常數(shù)兩類。數(shù)值常數(shù)可以有二進制、八進制、十進制、十六進制等不同的表示形式,匯編語言中采用不同的后綴加以區(qū)分。
B:表示二進制數(shù)。例如,10110011B。
D:表示十進制數(shù)。例如,179D(或略去D,記為179)。
O:表示八進制數(shù)。例如,263O。
H:表示十六進制數(shù)。例如,B3H。
例中的4個數(shù)據(jù)是以不同的基數(shù)形式表示的同一個數(shù)值。當(dāng)一個數(shù)值數(shù)據(jù)后面沒有后綴時,將默認為十進制數(shù)。字符串常數(shù)是由單引號括起來的一串字符。例如:‘THISISASUBROUTINE’,‘179’;要指出的是,此處的‘179’其值并不表示十進數(shù)179,而是1、7、9三個數(shù)字的ASCII碼,即31H、37H、39H。
最后還應(yīng)指出,匯編語言中的數(shù)值常數(shù)的第一位必須是數(shù)字,否則匯編時將被看成是標識符,例如十六進制數(shù)FFH應(yīng)表示成0FFH。
2.表達式
表達式由操作數(shù)和操作符組成。操作數(shù)可以是常數(shù)或標識符,也可以是表達式。操作符在匯編語言中非常豐富,包括算術(shù)操作符、邏輯操作符、關(guān)系操作符、屬性操作符及其它操作符等。這里主要說明前三種操作符。
算術(shù)操作符主要有:+、-、*、/、MOD。
算術(shù)運算都是雙操作數(shù)運算,操作數(shù)必須為數(shù)字操作數(shù)。取模運算(MOD)是取兩數(shù)相除的余數(shù),兩操作數(shù)的值必須為正整數(shù)。例如:
79MOD16 結(jié)果為15
0B5HMOD10H 結(jié)果為5邏輯操作符有:AND(邏輯與)、OR(邏輯或)、NOT(邏輯非)、XOR(邏輯異或)。
邏輯運算的操作數(shù)的值也應(yīng)為數(shù)字。匯編語言中的邏輯運算是位操作運算,運算時對應(yīng)位分別進行相應(yīng)運算。例如:
11001100B AND 11110000B 結(jié)果為11000000B
11001100B OR 11110000B 結(jié)果為11111100B
NOT 11110000B 結(jié)果為00001111B
11001100B XOR 11110000B 結(jié)果為00111100B值得注意的是,邏輯操作符同時又是邏輯運算指令的操作助記符,只有當(dāng)它們出現(xiàn)在指令的操作數(shù)部分時,才是邏輯操作符。例如,指令:
ANDAL,0CHOR0FH
其中,AND是指令的操作助記符,而OR是邏輯操作符。該指令將AL中的內(nèi)容與第二操作數(shù)的表達式的值(即兩數(shù)相或的結(jié)果)相與,結(jié)果存放于AL中。
關(guān)系操作符有:EQ(相等)、EN(不等)、LT(小于)、GT(大于)、LE(小于或等于)、GE(大于或等于)。關(guān)系運算的操作數(shù)也必須為數(shù)字操作數(shù)。當(dāng)關(guān)系成立時,其結(jié)果為真,用0FFFFH表示;當(dāng)關(guān)系不成立時,其結(jié)果為假,表示為0。
匯編語言中的表達式不能構(gòu)成單獨語句,只能是語句的一個部分,例如:
MOVAX,BUF+2
ADDAL,VALAND0FH
JMPAGAIN+3
MOVBL,VBLEVA
語句中表達式的求值不是在執(zhí)行指令時完成的,而是在對源程序進行匯編時完成的。所以,語句中各表達式的值在匯編時必須是確定的。3.1.4標號、變量及偽指令
1.標號
標號是寫在指令前的標識符,表示該指令在內(nèi)存中的存儲地址,也稱符號地址。
標號有三個屬性:段地址、偏移地址和類型。標號的段地址和偏移地址是指該標號對應(yīng)的指令所在段的段首址和段內(nèi)的偏移地址。標號的類型屬性有NEAR和FAR兩種。
標號定義成NEAR類型,表示該標號在段內(nèi)使用,而定義成FAR類型則表示該標號可以在段間使用。標號的定義方法是在指令的助記符前加上標識符和冒號,例如:
START:PUSHDS
這里,START為一標號,代表了指令PUSHDS所在內(nèi)存單元的地址。標號可以作為程序轉(zhuǎn)移指令的操作數(shù)(即要轉(zhuǎn)向的地址)。不是每條指令語句前都必須有標號。
2.變量
匯編語言與高級語言一樣也有變量,變量的值在程序運行期間是可以改變的。
1)變量定義
匯編語言中的變量是通過偽指令定義的,定義格式如下:
變量名DB表達式;定義字節(jié)變量(1字節(jié))
變量名DW表達式;定義字變量(2字節(jié))
變量名DD表達式;定義雙字變量(4字節(jié))
變量名DQ表達式;定義四字變量(8字節(jié))
變量名DT表達式;定義一個十字節(jié)變量
變量名是一個標識符。變量名后面只能用空格。變量的類型由變量名后的關(guān)鍵字DB、DW、DD、DQ、DT確定,它們分別定義了單字節(jié)變量(或稱字節(jié)變量)、雙字節(jié)變量(或稱字變量)、四字節(jié)變量(或稱雙字變量)、八字節(jié)變量(或稱長字變量)和十字節(jié)變量。
格式中的表達式可以有下面幾種情況:
(1)一個或多個常數(shù)或表達式。當(dāng)為多個常數(shù)或表達式時,其間用逗號隔開。
(2)帶引號的字符串,如例3.1中的變量DATA5、DATA6。
(3)一個問號‘?’,只定義一個變量,不賦初值。
(4)重復(fù)方式,此時表達式部分的格式為:重復(fù)次數(shù)DUP(表達式)。例3.1
DADA1
DB20H;
DATA2
DW0204H,1000H;
DATA3
DB(-1*3),(15/3);
DATA4
DD12345H;
DATA5
DB‘0123’;
DATA6
DW‘AB’,‘C’,‘D’
DATA7
DB?
DATA8
DD?
DATA9
DB5DUP(00)
DATA10
DW3DUP(?)上述偽指令的功能是在變量名所對應(yīng)的地址開始的內(nèi)存區(qū)依次存入表達式中的各項值。表達式中的每項值所占內(nèi)存的字節(jié)數(shù)與變量的類型相對應(yīng),見表3.1。表3.1各變量在內(nèi)存中的存放表3.1給出了例3.1中所定義的各變量在內(nèi)存存放的具體形式。表3.1中最左邊一列為內(nèi)存區(qū)的地址。假設(shè)變量DATA1的段地址和偏移地址為0100:0000H。中間一列為對應(yīng)內(nèi)存單元所存放的內(nèi)容,右邊一列為對應(yīng)的變量名。表3.1中的問號‘?’表示只分配地址,不給相應(yīng)單元賦值,該內(nèi)存單元中的內(nèi)容是不確定的,或者說,當(dāng)表達式為問號時,變量所對應(yīng)的內(nèi)存區(qū)在匯編過程中沒有確定數(shù)值,而只留出了相應(yīng)的存儲空間。如表3.1中地址為0100:0015H~0100:0019H單元中仍保持內(nèi)存中原來的內(nèi)容,而沒有送入確定的新值。重復(fù)方式指出表達式的值可以重復(fù)地存到變量對應(yīng)的內(nèi)存區(qū),重復(fù)的次數(shù)由偽指令給出。當(dāng)表達式的值為字符串時,對于字節(jié)類型變量,每個變量為一個字節(jié),每個字節(jié)內(nèi)存入一個字符的ASCII碼,整個字符串可以在同一個引號內(nèi)給出。對于字類型變量,每個變量的值不能超過2個字符,若為2個字符時同樣遵循高位存入高字節(jié),低位存入低字節(jié)的規(guī)則;若為1個字符時,該字符的ASCII碼存入低字節(jié),高字節(jié)為00。對于雙字長字類型變量,每個變量的值也不能超過2個字符并存入2個低位字節(jié)。
2)變量的屬性
變量具有下列屬性:
(1)段地址(SEG):變量所在段的首地址。
(2)偏移地址(OFFSET):變量相對于所在段首地址的地址偏移。
(3)類型(TYPE):變量的類型是所定義的每個變量所占據(jù)的字節(jié)數(shù),對于DB、DW、DD、DQ、DT定義的變量,其類型值分別為1、2、4、8、10。通常又將DB、DW、DD所定義的變量分別稱為BYTE類型、WORD類型、DWORD類型的變量。
(4)長度(LENGTH):變量定義時,一個變量名所定義的變量個數(shù)。在含有DUP操作符的變量定義中,變量名所定義的變量個數(shù)為定義格式中的重復(fù)次數(shù)。在其它各種變量定義中,每個變量名所定義的變量個數(shù)均為1。
(5)大小(SIZE):變量定義語句中,分配給同一變量名的所有變量的總的字節(jié)數(shù),其值為該變量的類型與長度的乘積。
例3.1中所定義的部分變量的屬性值列于表3.2中。表3.2部分變量的屬性3.1.5屬性操作符及表達式
前面我們已介紹了幾種操作符及其表達式,這些操作符的操作對象都是數(shù)值數(shù)據(jù)。下面我們將介紹用來獲取屬性或重新定義某種屬性的操作符,稱其為屬性操作符。對應(yīng)這樣的操作符,也有其相應(yīng)的表達式。
1.獲取屬性的操作符
標號或變量一旦定義,它們都具有相應(yīng)的屬性,獲取屬性的操作符及其表達式列于表3.3中。表3.3操作符及其表達式例如對表3.1中所定義的各變量,有:
SEGDATA1 ;結(jié)果為0100H
OFFSETDATA1 ;結(jié)果為0000
LENGTHDATA6 ;結(jié)果為1
TYPEDATA6 ;結(jié)果為2
SIZEDATA9 ;結(jié)果為5
這些表達式與上面提到的運算表達式一樣,不能構(gòu)成單獨的語句,只能是語句的一個成分,并且表達式的求值也是在匯編過程中完成的。有如下的變量定義:
DAT1DB 02H
DAT2DW 0F00H
DAT3DW 5DUP(?)
DAT4DB LENGTHDAT3
DAT5DW DAT3
經(jīng)匯編以后,DAT4對應(yīng)的內(nèi)存單元中存放的是變量DAT3的長度(即5),DAT5所對應(yīng)的2個字節(jié)中存放的將是變量DAT3的偏移地址。
2.?PTR操作符
格式:類型PTR表達式
格式中的類型可以是:BYTE、WORD、DWORD、NEAR和FAR。前三個類型為變量類型,后兩個為標號類型。格式中的表達式可以是變量名、標號或其它地址表達式。
PTR操作符的功能是用來重新定義已定義的變量或標號的類型。例如上例中的變量DAT3是字變量,若程序中需將它作為字節(jié)變量使用時,必須用PTR操作來重新定義其類型??梢杂?/p>
MOVBYTEPTRDAT3,AL這里將DAT3重新定義為字節(jié)類型。?整個語句的功能將是AL中的內(nèi)容送到DAT3對應(yīng)的一個字節(jié)中。要指出的是變量DAT3僅在該語句中作為字節(jié)變量使用,DAT3原來定義的字變量類型并沒有修改。 3.2Intel80x86系列CPU指令系統(tǒng)
CPU的指令系統(tǒng)是指該CPU所有機器指令的集合,它是在CPU設(shè)計時就確定了的。指令系統(tǒng)是表征一種CPU性能的重要因素。?不同CPU的指令系統(tǒng)中所包含的指令是不相同的。習(xí)慣上將美國Intel公司設(shè)計生產(chǎn)的8086系列CPU統(tǒng)稱為Intel80x86CPU,包括早期的8088、8086、80286、80386、80486及最新的奔騰CPU。Intel80x86系列CPU采用了軟硬件兼容的設(shè)計思想,即最新設(shè)計的CPU在指令系統(tǒng)和硬件資源方面兼容以前生產(chǎn)的CPU。最早設(shè)計的8086CPU的指令系統(tǒng)構(gòu)成了Intel80x86系列CPU指令系統(tǒng)的基本核心,后續(xù)推出的各種CPU的指令系統(tǒng),如80386、80486及最新的奔騰CPU等,都包含了8086指令系統(tǒng),并在此基礎(chǔ)上進行了擴展。按照功能可將80x86指令分成下面幾類:
(1)數(shù)據(jù)傳送指令;
(2)算術(shù)運算指令;
(3)邏輯運算指令;
(4)移位指令;
(5)標志處理指令和CPU控制指令;
(6)轉(zhuǎn)移和循環(huán)控制指令;
(7)調(diào)用和返回指令;
(8)字符串操作指令;
(9)輸入、輸出指令。對于指令系統(tǒng)的介紹,重點將放在各條指令的功能和它們的使用上。學(xué)習(xí)指令系統(tǒng)著重要掌握指令的基本操作功能、合法的尋址方式以及對標志位的影響。本書中描述指令操作時用到的各種縮寫和符號列于表3.4中。表3.4縮?寫?與?符?號3.2.1數(shù)據(jù)傳送類指令
數(shù)據(jù)傳送指令負責(zé)把數(shù)據(jù)、地址或立即數(shù)送到寄存器或存儲單元中,指令基本格式及功能說明見表3.5。表中除了SAHF和POPF指令外,標志寄存器F的各位均不受影響。指令中出現(xiàn)兩個操作數(shù)時,目的操作數(shù)在前,源操作數(shù)在后,并且目的操作數(shù)不能為立即數(shù)和段寄存器CS。表3.5數(shù)據(jù)傳送類指令的格式與功能
1.通用傳送指令(MOV)
格式:MOVDST,SRC
執(zhí)行操作:(DST)←(SRC)
功能:將操作數(shù)從SRC傳輸?shù)紻ST。
源操作數(shù)可以是通用寄存器、段寄存器、立即數(shù)和內(nèi)存單元;目的操作數(shù)可以是通用寄存器、段寄存器和內(nèi)存單元,但不能為立即數(shù)和CS。內(nèi)存單元可以通過第2章所指出的各種尋址方式尋址。當(dāng)目的操作數(shù)為段寄存器時,源操作數(shù)不能為立即數(shù);當(dāng)源操作數(shù)不是立即數(shù)時,兩個操作數(shù)中必須有一個是寄存器。例如:上述指令都是合法的。前兩條指令的源操作數(shù)與目的操作數(shù)的尋址方式均為寄存器尋址方式;第3條指令的目的操作數(shù)仍為寄存器尋址方式,而源操作數(shù)的尋址方式則為立即數(shù)方式;第4條指令的源操作數(shù)為寄存器間接尋址,源操作數(shù)的有效地址為BX的內(nèi)容即EA=(BX),因而指令的功能是將EA所對應(yīng)單元中的一個字送入SI。
下面著重說明后面三條指令的尋址方式和傳送過程。
1)?MOVAL,4[DI]
該指令的源操作數(shù)為寄存器相對尋址方式,或稱變址尋址方式,其有效地址EA=(DI)+4,EA即為源操作數(shù)在段內(nèi)的偏移地址。?指令的功能是將有效地址EA所對應(yīng)的單元中的一個字節(jié)送入AL中,當(dāng)(DI)=0400H時,該指令執(zhí)行后,AL中的內(nèi)容為0AH。指令的傳送過程見圖3.1(a)。圖3.1指令的傳送過程(a)?MOVAL,4[DI]傳送過程;(b)?MOVAX,[BX+2]傳送過程;(c)?MOV[BX][DI],DX傳送過程
2)?MOVAX,[BX+2]
該指令的源操作數(shù)的尋址方式也為寄存器相對尋址方式(或稱基址尋址方式),其有效地址EA=(BX)+2,當(dāng)(BX)=1000H時,那么,EA=1002H,指令的功能是將EA所對應(yīng)單元中的一個字送入AX。由于一個字的數(shù)據(jù)在內(nèi)存占據(jù)兩個字節(jié)單元,所以,該指令完成的傳送應(yīng)為(EA)→(AL),(EA+1)→(AH),傳送過程見圖3.1(b)。
3)?MOV[BX][DI],DX
該指令的源操作數(shù)的尋址方式為寄存器方式,目的操作數(shù)的尋址方式為基址變址尋址方式,其有效地址EA=(BX)+(DI)。指令的功能是將DX中的16位數(shù)送入有效地址EA所指的2個字節(jié)單元中,具體過程應(yīng)為(DL)→(EA),(DH)→(EA+1)。傳送過程見圖3.1(c)。
當(dāng)程序中采用偽指令定義了一組變量后,傳送指令可以有下面的形式:上述傳送指令都是合法的。第1條指令的源操作數(shù)和第2條指令的目的操作數(shù)的尋址方式為直接尋址方式,其有效地址EA即為變量DATA1和DATA3的偏移地址,可以表示為EA=OFFSETDATA1和EA=OFFSETDATA3。所以第1條指令的功能是將變量DATA1對應(yīng)地址單元中的一個字送入AX,故(AX)=0020H。第3條指令的源操作數(shù)和第4條指令的目的操作數(shù)的尋址方式為寄存器相對尋址方式,其有效地址分別為EA=(DI)+?OFFSETDATA2和EA=(SI)+OFFSETDATA3,即將變址寄存器的內(nèi)容加上變量DATA1或DATA3的偏移地址。若(DI)=1,(SI)=0,(DX)=103FH,那么,執(zhí)行第3條指令后,(AL)=60H,第4條指令執(zhí)行后偏移地址為DATA3的內(nèi)存單元內(nèi)容為3FH,下一單元的內(nèi)容為10H。第5條指令采用了表達式LENGTHDATA3,即取變量DATA3的長度,由于變量定義時DATA3分配了10H個字變量空間,所以,該指令執(zhí)行后,(CX)=10H。第6條指令取的是變量DATA3所占的字節(jié)數(shù),所以,指令執(zhí)行后(BX)=20H。第7條指令用了操作符OFFSET,它是將DATA2的偏移地址送入SI。最后3條指令的尋址方式均屬于立即數(shù)尋址方式,因為在匯編后,源操作數(shù)已是已知的確定數(shù)值了。指令中傳送的是一個字還是一個字節(jié),通常由操作數(shù)的類型確定。當(dāng)操作數(shù)是寄存器時,那么,16位寄存器將指出該操作數(shù)為字類型,8位寄存器則指出對應(yīng)的操作數(shù)為字節(jié)類型,若操作數(shù)是某種尋址方式所指出的內(nèi)存單元時,那么,相應(yīng)的操作數(shù)的類型有時是明確的,而有時可能是不明確的。如下面3條指令:
MOVDATA3[SI],02
MOV2[SI],AL
MOV4[DI],02上述指令中的目的操作數(shù)均為寄存器相對尋址方式所指的內(nèi)存某單元,第1條指令的目的操作數(shù)的類型將取決于變量DATA3的類型,只要變量DATA3已定義,其類型是明確的,而后兩條指令的目的操作數(shù)的類型就不明確了,但因第2條指令的源操作數(shù)的類型是明確的,從而指令屬于字節(jié)傳送。第3條指令因源操作數(shù)與目的操作數(shù)的類型均不明確,因而為非法指令,此時,必須用前面介紹的PTR操作符來指明其操作類型,格式如下:
MOVBYTEPTR4[DI],02
這樣就指出了指令為字節(jié)操作。此外,傳送指令的兩個操作數(shù)的類型必須一致,否則,指令將為非法指令。對于通用傳送類指令,應(yīng)著重掌握的是進行傳送的兩個操作數(shù)的尋址方式及其書寫格式,也就是傳送數(shù)據(jù)的兩個操作數(shù)的有效地址以什么方式獲得,并在指令中如何表示。這些尋址方式及其書寫格式不僅適用于傳送類指令,同樣也適用于其它各類指令。下面對通用傳送指令中與尋址方式有關(guān)的內(nèi)容歸納如下:
(1)兩操作數(shù)進行數(shù)據(jù)傳送的正常通路如圖3.2所示。圖中的箭頭指出了兩者之間可以進行數(shù)據(jù)傳送的方向。例如存儲器與寄存器AX、BX、CX、DX、DI、SI、SP、BP之間可以雙向傳送,而存儲器與段寄存器CS之間只能單向傳送。圖3.2數(shù)據(jù)傳送的正常通路
(2)寄存器間接尋址、寄存器相對尋址、基址變址尋址和基址變址相對尋址方式中所用到的寄存器不能是數(shù)據(jù)寄存器AX、CX和DX,只能使用變址寄存器DI、SI和基址寄存器BX、BP。
(3)寄存器相對尋址和寄存器基址變址相對尋址方式中的位移量DISP可以是常量,也可以是變量,并且可以有多種書寫格式。下面以寄存器相對尋址為例,給出幾種可用的書寫格式:
MOVAX,DISP[BX]
MOVAX,[BX+DISP]
MOVAX,[BX].DISP
MOVAX,[BX]+DISP
上述4條指令的功能是完全一樣的,源操作數(shù)的有效地址均為EA=(BX)+DISP。指令中的寄存器BX也可以是其它的基址、變址寄存器。按某種尋址方式計算得到的有效地址是段內(nèi)的偏移地址,對于某存儲單元的完整地址還應(yīng)包括其段地址,段地址則在相應(yīng)的段寄存器中。數(shù)據(jù)段的段地址在DS中,在執(zhí)行上述指令之前,首先必須通過傳送指令將段地址送入段寄存器DS中。例如可以采用下面兩條傳送指令:
MOVAX,SEGDATA1 ;將變量DATA1的段地址送入AX
MOVDS,AX若程序中所用的數(shù)據(jù)段的段址寄存器不是DS,而是ES,那么,指令中必須用段前綴加以說明,其格式為
MOVAX,ES:[SI]
它告訴匯編程序,這條指令中要取的數(shù)據(jù)的段址在ES中,而不在DS中,匯編后形成的機器指令也增加一個前綴字節(jié),以說明所用的段寄存器。
2.取有效地址指令(LEA)
格式:LEAREG,SRC
執(zhí)行操作:(REG)←SRC
功能:將源操作數(shù)SRC的有效地址(偏移地址)送入寄存器REG中。
這里的REG不允許是段寄存器,源操作數(shù)的尋址方式不允許是立即數(shù)和寄存器方式。這是一條特殊指令,它傳送的不是操作數(shù)本身,而是操作數(shù)的有效地址。為說明問題,比較下面兩行指令執(zhí)行的結(jié)果:
MOVAX,10H[DI]
LEAAX,10H[DI]假設(shè)(DI)=0500H,(DS)=0200H,對應(yīng)內(nèi)存單元的內(nèi)容如圖3.3所示。那么,第一條指令執(zhí)行后,AX的內(nèi)容為(AX)
=00FFH,它是將0200H段中的偏移地址為0510H處的16位數(shù)送入AX。第二條指令執(zhí)行后,AX的內(nèi)容為(AX)=0510H,也即將源操作數(shù)的有效地址的偏移地址送入了AX。
取有效地址指令也可以有下面的形式:
LEADI,DATA1
LEABX,AGAIN指令中的DATA1及AGAIN可以是已定義的變量,也可以是程序中的語句標號,不論是變量還是標號,它們都有段和偏移地址的屬性。在該指令中,它們將取變量或標號的偏移地址送入相應(yīng)的寄存器。所以,下面兩條指令是完全等效的:
MOVAX,OFFSETDATA1
LEAAX,DATA1圖3.3內(nèi)存單元的內(nèi)容
3.取地址指針指令(LDS,LES)
格式:LDSREG,SRC
LESREG,SRC
執(zhí)行操作:(REG)←(SRC),(SREG)←(SRC+2)
功能:?該指令的功能是將源操作數(shù)SRC的有效地址所對應(yīng)的內(nèi)存單元中的32位內(nèi)容分別送入DS(或ES)和指令中所指出的寄存器REG中。同樣,這里的REG不允許為段寄存器,源操作數(shù)的尋址方式不允許是立即數(shù)和寄存器方式。可以有下面的變量定義和指令:
TABLEDB10H,20H,30H,40H,50H
POINT1DD02001000H
POINT2DDTABLE
…
LDSDI,POINT1
LESSI,POINT2指令LDSDI,POINT1執(zhí)行后,(DI)=1000H,(DS)=0200H;指令LESSI,POINT2執(zhí)行后,(SI)=OFFSETTABLE,(ES)=SEGTABLE。需要指出的是,匯編后雙字變量POINT2中的32位內(nèi)容將是變量TABLE的32位地址,其高16位是TABLE的段地址,低16位是TABLE的偏移地址,這正是雙字變量的一種重要用途。上面兩條指令的源操作數(shù)的尋址方式為直接尋址方式,也可采用其它尋址方式,但不同尋址方式所指的內(nèi)存單元都應(yīng)是雙字類型。
4.標志傳送指令(LAHF,SAHF)
CPU中有一標志寄存器FLAG,其中的每一位標志了CPU的一種狀態(tài)。許多指令的執(zhí)行結(jié)果會影響標志寄存器中的某些位,同時,有些指令的執(zhí)行也受標志寄存器中的某些位控制。標志寄存器的內(nèi)容與指令的執(zhí)行有著密切的關(guān)系?,F(xiàn)在介紹的兩條指令實現(xiàn)標志寄存器中的低8位與寄存器AH之間的傳送。
格式:LAHF
SAHF功能:LAHF是將標志寄存器中的低8位內(nèi)容送入寄存器AH,SAHF是將AH中的8位內(nèi)容送入標志寄存器的低8位中。顯然,SAHF指令可以同時改變標志寄存器FLAG的低8位中的各位的值。
5.數(shù)據(jù)交換指令(XCHG)
格式:XCHGOPR1,OPR2
執(zhí)行操作:(OPR1)←→?(OPR2)
功能:完成寄存器與寄存器或寄存器與存儲單元之間的內(nèi)容交換。該指令要求兩個操作數(shù)之一必須是寄存器,允許兩個操作數(shù)都是寄存器,但不允許是段寄存器。例如:
XCHGAX,BX;(AX)←→?(BX)
XCHGCX,[DI];(CX)←→?([DI])
XCHGBX,DATA1上述指令都是合法的,其中第2條指令和第3條指令完成的是寄存器與內(nèi)存單元的內(nèi)容交換。第2條指令源操作數(shù)為寄存器間接尋址,即由DI的內(nèi)容指明了要交換的內(nèi)存單元的偏移地址。第3條指令的源操作數(shù)為直接尋址,DATA1是已定義的變量,DATA1的偏移地址直接指明了要交換數(shù)據(jù)的內(nèi)存單元的偏移地址。
6.字節(jié)轉(zhuǎn)換指令(XLAT)
格式:XLAT
執(zhí)行操作:(AL)←((BX)+(AL))
功能:該指令的尋址方式是隱含的,其有效地址EA=(BX)+(AL)。指令的功能是將EA所對應(yīng)的內(nèi)存單元中的一個字節(jié)送入AL中。
該指令可用于兩種代碼的轉(zhuǎn)換,例如要將表3.6中的代碼CODE1轉(zhuǎn)換成代碼CODE2,只要將表中的代碼CODE2依次存入地址連續(xù)的內(nèi)存單元中,如表3.7所示,那么,若將其首地址TABLE送入BX,將需要轉(zhuǎn)換的一個CODE1的代碼送入AL,執(zhí)行XLAT指令后,AL中便是對應(yīng)的CODE2的代碼了。例如,求CODE1代碼中的5所對應(yīng)的CODE2代碼,可以用下面的程序段:
MOVAX,SEGTABLE
MOVDS,AX
MOVBX,OFFSETTABLE
MOVAL,05
XLAT
該程序段執(zhí)行后,(AL)=35H。表3.6代碼轉(zhuǎn)換表3.7內(nèi)存單元
7.堆棧操作指令
1)堆棧
堆棧是以后進先出(LIFO)的規(guī)則存取信息的一種存儲機構(gòu)。在PC機中,堆棧通常是存儲器的一部分。為了保證堆棧區(qū)的存儲器能按后進先出的規(guī)則存取信息,該存儲區(qū)的存取地址由一個專門的地址寄存器來管理,這個地址寄存器稱為堆棧指示器或稱堆棧指針SP。當(dāng)信息存入堆棧(通常稱為進棧)時,堆棧指針將自動減量并將信息存入堆棧指針所指出的存儲單元,當(dāng)需要從堆棧中取出信息(通常稱為出棧)時,也將從堆棧指針所指出的存儲單元中讀取信息,并自動將堆棧指針增量。所以,堆棧指針始終指向堆棧中最后存入信息的那個單元,我們稱該單元為堆棧頂。在信息的存與取的過程中,棧頂是不斷移動的,也稱它為堆棧區(qū)的動端,而堆棧區(qū)的另一端則是固定不變的,這端被稱為棧底。堆棧指針寄存器用來存放堆棧區(qū)的偏移地址,當(dāng)堆棧地址長度為16位時,用SP作為堆棧指針寄存器,當(dāng)堆棧地址長度為32位時(80386及其后繼機型)用ESP。堆棧區(qū)的段地址則存于段寄存器SS中。SP或ESP的內(nèi)容在任何時刻都指向棧頂。堆棧的存取在16位指令中必須以字為單位(不允許字節(jié)堆棧),在32位指令中必須以雙字為單位。
在程序設(shè)計中,堆棧是十分有用的一種結(jié)構(gòu)。后面要介紹的子程序的調(diào)用與返回都將離不開堆棧。此外,堆棧還可以用來保存程序中的某些信息,這些信息需要以后進先出的規(guī)則存取。在輸入輸出系統(tǒng)中,中斷響應(yīng)和返回的正確操作也必須由堆棧來保證。
2)堆棧操作指令
堆棧的主要操作是對堆棧進行信息的存取,將信息送入堆棧的過程稱為進棧操作,從堆棧中取出信息的過程稱為出棧操作。指令的助記符及功能說明見表3.5。
(1)進棧指令(PUSH)。
格式:PUSHSRC
執(zhí)行操作:(SP)←(SP)-2,((SP)+1,(SP))←(SRC)上述都是合法指令。第1條指令是將AX中的內(nèi)容送入堆棧。首先,SP內(nèi)容減2,然后,將AL的內(nèi)容送入SP所指單元,AH的內(nèi)容送入(SP)+1所指單元。第2條指令是將段寄存器的16位內(nèi)容送入堆棧,并修正SP內(nèi)容。第3條指令是將內(nèi)存某單元的16位內(nèi)容送入堆棧。同樣,首先將SP內(nèi)容減2,然后,將(SI)所指單元的8位內(nèi)容送入(SP)所指單元,((SI)+1)所指單元的8位內(nèi)容送入((SP)+1)所指單元。?最后一條指令是將標志寄存器的內(nèi)容壓入堆棧,其過程與上面相同,其低位送入低字節(jié),高位送入高字節(jié)。應(yīng)注意的是,進棧指令不能將一個常數(shù)壓入堆棧,若需要將一常數(shù)送入堆棧,必須通過寄存器來實現(xiàn)。例如:
MOVAX,0FFFFH
PUSHAX
(2)出棧指令(POP)。
格式:POPDST
執(zhí)行操作:(DST)←((SP)+1,(SP)),(SP)←(SP)+2
功能:將SP所指出的棧頂?shù)膬?nèi)容取出,并送入DST所指寄存器、內(nèi)存某單元或標志寄存器FLAG,并修正SP內(nèi)容。
DST也必須為字類型,它可以是通用寄存器和除了CS以外的段寄存器,也可以是某種尋址方式所指的內(nèi)存單元,但不能為立即數(shù)。指令POP?DST對標志位不產(chǎn)生影響。由于SP所指的就是堆棧中最后存入信息的單元,彈出指令正是彈出該單元的內(nèi)容,所以,執(zhí)行POP指令時先彈出棧頂內(nèi)容,后修正SP的內(nèi)容,并且SP以加2修正。若有下面的程序段:
MOVSP,0100H
PUSHAX
PUSHBX
POPAX
POPBX
則程序執(zhí)行后,SP將仍指向0100H單元,即(SP)=0100H,而寄存器AX,BX的內(nèi)容進行了交換。這告訴我們,程序中的PUSH指令與POP指令若成對出現(xiàn),那么,程序執(zhí)行后,堆棧指針將保持程序執(zhí)行前的內(nèi)容,或者說棧頂位置保持不變。
8.符號擴展傳輸和零擴展傳輸指令(80386及以后微處理器)
1)?MOVSX帶符號擴展傳送指令
格式:MOVSX?DST,SRC
執(zhí)行操作:(DST)←符號擴展(SRC)
該指令的源操作數(shù)可以是8位或16位的寄存器或存儲單元的內(nèi)容,而目的操作數(shù)則必須是16位或32位寄存器,傳送時把源操作數(shù)進行符號擴展,即將SRC內(nèi)容送入DST的低位,用SRC的符號位填充DST的高位??梢允?位符號擴展到16位,也可是16位符號擴展到32位。MOVSX不影響標志位。
2)?MOVZX帶零擴展傳送指令
格式:MOVZX?DST,SRC
執(zhí)行操作:(DST)←零擴展(SRC)
該指令的源操作數(shù)可以是8位或16位的寄存器或存儲單元的內(nèi)容,而目的操作數(shù)則必須是16位或32位寄存器,傳送時把源操作數(shù)進行零擴展,即將SRC內(nèi)容送入DST的低位,用0填充DST的高位??梢允?位符號擴展到16位,也可是16位符號擴展到32位。MOVSX不影響標志位。3.2.2算術(shù)運算類指令
1.加法與減法指令
加法與減法指令的助記符格式及其功能說明見表3.8。指令中參加運算的兩個操作數(shù)一個稱為目的操作數(shù)(DST),一個為源操作數(shù)(SRC),運算結(jié)束后,目的操作數(shù)被運算結(jié)果所代替,源操作數(shù)保持不變。加、減法指令對標志寄存器的各位均有影響。表3.8加法與減法指令的助記符與功能指令中兩操作數(shù)可以采用多種尋址方式。源操作數(shù)可以為立即數(shù)、通用寄存器和任一尋址方式所指定的內(nèi)存單元。目的操作數(shù)可以為通用寄存器和任一尋址方式所指定的內(nèi)存單元,但不允許是立即數(shù)。當(dāng)源操作數(shù)不是立即數(shù)時,兩個操作數(shù)中必須有一個是寄存器。例如下面的指令都是合法的:上述指令中,第1條與第5條指令為8位數(shù)運算指令,其余均為16位數(shù)運算指令。無論是8位數(shù)運算還是16位數(shù)運算,兩個操作數(shù)的類型必須一致,否則為非法指令。如上面的最后一條指令,變量DATA1必須是字變量,否則將因類型不一致而非法。
上述指令中的最后兩條指令是帶進位的加、減運算,即在運算時,除了完成指令所指出的兩個操作數(shù)的加、減運算外,還必須考慮進位(或借位)標志CF的當(dāng)前狀態(tài)。對于ADC指令,則在實現(xiàn)兩操作數(shù)的加法運算基礎(chǔ)上應(yīng)加上CF的當(dāng)前值;對于SBB指令,則在實現(xiàn)兩操作數(shù)的相減運算的基礎(chǔ)上還應(yīng)減去CF的當(dāng)前值。應(yīng)該注意,CF的當(dāng)前值是由程序中本指令之前的指令產(chǎn)生的。下面分析兩條指令的執(zhí)行結(jié)果,以說明指令的功能。
1)?ADDAX,[SI]
該指令為16位數(shù)加法指令,目的操作數(shù)的尋址方式為寄存器方式,源操作數(shù)的尋址方式為寄存器間接方式,其功能是將AX的內(nèi)容與寄存器SI的內(nèi)容所指的內(nèi)存單元中的16位數(shù)相加,結(jié)果送入AX,并設(shè)置標志寄存器FLAG各位。執(zhí)行過程見圖3.4。
本節(jié)所討論的指令對標志寄存器中DF、IF、TF均不產(chǎn)生影響。
CF作為進位(或借位)標志時是對無符號數(shù)而言的,?而OF作為溢出標志是對帶符號數(shù)而言的。不論是無符號數(shù)還是帶符號數(shù),在執(zhí)行指令時的運算是完全一樣的,包括對標志位的影響也沒有區(qū)別。圖3.4ADDAX,[SI]執(zhí)行過程
2)?SBBCX,DATA1
該指令為帶借位的16位數(shù)減法指令,目的操作數(shù)的尋址方式為寄存器方式,源操作數(shù)的尋址方式為直接方式。其功能是CX中的16位數(shù)減去變量DATA1對應(yīng)的內(nèi)存單元中的16位數(shù)及標志寄存器中CF的當(dāng)前值,相減后的差值送寄存器CX,并設(shè)置標志寄存器FLAG的各位。執(zhí)行過程見圖3.5。圖3.5SBBCX,DATA1執(zhí)行過程圖3.5中指出,指令執(zhí)行前(CX)=3F50H,變量DATA1在數(shù)據(jù)段內(nèi)的偏移地址為0006H,對應(yīng)單元中的16位數(shù)為1728H,借位標志(CF)=1。指令執(zhí)行后其結(jié)果如下:
在減法指令中,標志位CF和AF分別為最高位和第3位向高位的借位,其余各位的含義與加法指令相同。由于SBB指令是一條帶借位的減法指令,因此,應(yīng)注意該指令執(zhí)行前借位標志的當(dāng)前值。對于ADC指令有相同的情況。
帶進位的加、減法指令主要用于多位數(shù)的加、減運算。例如在內(nèi)存中偏移地址為ADR1開始的連續(xù)單元中存放著兩個4字節(jié)操作數(shù)A和B,求該兩數(shù)之和C,并將結(jié)果存放于偏移地址為ADR2開始的連續(xù)單元中,如圖3.6所示。在8086指令系統(tǒng)中,加法指令只能完成兩個8位數(shù)相加或兩個16位數(shù)相加,如要完成32位數(shù)(4個字節(jié))的相加,必須分兩步實現(xiàn)。首先完成低16位數(shù)的相加,并保存所得的和與進位值,然后再完成高16位數(shù)的相加,并加上低16位數(shù)相加時可能產(chǎn)生的進位。這樣,32位數(shù)的相加就完成了。在此基礎(chǔ)上,可以實現(xiàn)更多位數(shù)的相加運算。對于80386及其后繼機型,32位的加法和減法運算則可以直接用一條ADD或SUB指令完成。圖3.6多位數(shù)的加法
2.比較指令
格式:CMPDST,SRC
執(zhí)行操作:(DST)-(SRC),根據(jù)結(jié)果設(shè)置標志位
功能:目的操作數(shù)減去源操作數(shù),并根據(jù)相減結(jié)果置各標志位。指令中兩操作數(shù)的尋址方式與加、減法指令的尋址方式相同。它與減法指令不同的是所產(chǎn)生的兩數(shù)之差并不取代目的操作數(shù),因而指令執(zhí)行后,僅僅改變了標志寄存器的內(nèi)容,兩操作數(shù)的值保持不變。指令中兩操作數(shù)的類型必須一致。比較指令可以有如下的形式:
CMPAL,BL
CMPAL,[DI]
CMPAX,CX
CMPAX,06H
上述指令都是合法的,前兩條指令為8位數(shù)比較指令,后兩條指令為16位數(shù)比較指令。
比較指令執(zhí)行后的結(jié)果僅僅體現(xiàn)在標志寄存器中,它是為后面的具有判別功能的指令提供條件的。
3.增量和減量指令
指令助記符格式及其功能說明見表3.9。兩條指令均為單操作數(shù)指令,操作數(shù)的尋址方式可采用除立即數(shù)外的各種尋址方式,但不能是段寄存器。指令的功能是對目的操作數(shù)加1或減1。指令除對進位標志CF不影響外,其余標志都受影響。表3.9增量和減量指令助記符與功能有下面的合法指令:
INCAL ;(AL)←(AL)+1
INCBX ;(BX)←(BX)+1
INCWORDPTR4[BX] ;((BX)+4)←((BX)+4)+1
DECCX ;(CX)←(CX)-1
指令可以為字操作和字節(jié)操作兩種,指令中還必須明確其操作類型。如上面的第3條指令必須用PTR操作符指出指令要對內(nèi)存中的一個16位數(shù)加1,而不是對8位數(shù)加1。
4.乘法與除法指令
指令助記符格式及其功能說明見表3.10。表3.10乘法和除法指令助記符與功能乘除法指令分帶符號運算和不帶符號運算兩種。帶符號運算時,操作數(shù)和結(jié)果均以補碼表示。
乘法指令中的目的操作數(shù)的尋址方式是隱含的,并且一定是累加器AX或AL。源操作數(shù)的尋址方式可采用除立即數(shù)以外的各種尋址方式,但不能是段寄存器。
指令是字運算還是字節(jié)運算由源操作數(shù)的類型確定。當(dāng)字運算時,目的操作數(shù)為AX,相乘后的32位結(jié)果送DX:AX,DX中為高16位,AX中為低16位。當(dāng)字節(jié)運算時,目的操作數(shù)為AL,相乘后的16位結(jié)果送AX。乘法指令執(zhí)行后,標志寄存器中只有CF和OF位有意義,其它各位的值均為不確定。對于MUL指令,若相乘后的結(jié)果中高16位(字運算)或高8位(字節(jié)運算)均為0,則CF和OF被置為0,否則CF和OF被置為1。對于IMUL指令,若相乘后的結(jié)果中高16位或高8位為低16位或低8位的符號擴展,則CF和OF被置為0,否則CF和OF被置為1。所以,標志位CF和OF可用來判斷相乘的結(jié)果中高位字或高位字節(jié)是否有值。下面的乘法指令均是合法的:
MULDAT1 ;(DX:AX)←(AX)*(DAT1)
IMULCL ;(AX)←(AL)*(CL)
MULBYTEPTR[BX] ;(AX)←(AL)*([BX])
上述指令中的第1條指令的操作類型由變量DAT1確定,由指令的注釋可以看出,DAT1一定是字變量。第2條指令的操作類型是明顯的,即為字節(jié)操作。第3條指令的源操作數(shù)在BX所指出的內(nèi)存某單元中,此時必須用PTR操作符來明確源操作數(shù)的類型,否則指令將為非法。
5.符號擴展指令
有時會遇到兩個長度不等的數(shù)進行加、減法運算,此時,應(yīng)將長度短的數(shù)的位數(shù)擴展,以使兩數(shù)的長度一致,只有這樣,才能保證參加運算的兩個操作數(shù)的類型是一致的。此外,除法指令中的被除數(shù)必須放在AX或DX:AX中,因此有時也需要將一個8位或16位數(shù)進行擴展。對于一個無符號數(shù)來說,這種擴展是簡單的,只要將其高位補“0”就可以,但對一個帶符號數(shù)來說就不一樣了,擴展時高位補“0”還是補“1”,取決于被擴展數(shù)的符號位,也就是說,當(dāng)被擴展數(shù)是正數(shù)時高位應(yīng)補“0”,為負數(shù)時高位應(yīng)補“1”。表3.11中的兩條指令就是實現(xiàn)帶符號數(shù)擴展功能的。它們都是單操作數(shù)指令,其尋址方式是隱含的,并且一定為AL或AX。
指令CBW是將AL中的一個字節(jié)擴展成AX中的一個字,擴展后AH中的內(nèi)容與AL中的最高位(符號位)一致。指令CWD是將AX中的一個字擴展成DX:AX中的一個雙字,擴展后DX中的內(nèi)容與AX中的最高位一致。例如,AL中的內(nèi)容為0F2H,那么執(zhí)行指令CBW后AX中的內(nèi)容將為0FFF2H。顯然,擴展前后的兩個數(shù)都是-0EH的補碼。表3.11符號擴展指令助記符與功能
6.?BCD數(shù)調(diào)整指令
指令助記符格式及其功能列于表3.12中。指令的操作數(shù)均為隱含尋址,并且為AL或AX。表3.12BCD數(shù)調(diào)整指令助記符與功能
BCD數(shù)是用4位二進制碼表示的一位十進制數(shù)。在計算機中,所有運算均以二進制運算為基礎(chǔ),要實現(xiàn)對BCD數(shù)進行十進制運算,通常分兩步進行,首先對BCD數(shù)按二進制進行運算,然后對運算結(jié)果進行相應(yīng)的調(diào)整。本書對本組指令不加詳細說明,讀者如有需要,請查閱相關(guān)手冊。
3.2.3邏輯運算類指令
邏輯運算指令的格式及功能說明列于表3.13。表3.13邏輯運算指令格式與功能指令中源操作數(shù)可以為立即數(shù)、通用寄存器和任一尋址方式所指定的內(nèi)存單元。目的操作數(shù)可以為通用寄存器和任一尋址方式所指定的內(nèi)存單元,但不允許是立即數(shù),當(dāng)源操作數(shù)不是立即數(shù)時,兩個操作數(shù)中必須有一個是寄存器。
指令的運算都是按位進行的。NOT指令是將操作數(shù)的各位取反,其它指令則是兩個操作數(shù)的對應(yīng)位執(zhí)行相應(yīng)的邏輯運算。指令可以是字節(jié)操作,也可以是字操作。除了NOT指令對標志位不產(chǎn)生影響外,其余指令將使CF、OF置0,并以正常規(guī)則設(shè)置SF、ZF和PF的狀態(tài)。例如:表3.14指令及執(zhí)行后的結(jié)果表3.14中結(jié)果項給出了指令執(zhí)行后,標志寄存器的各位以及有關(guān)寄存器和變量對應(yīng)單元的內(nèi)容。累加器AX的內(nèi)容包含了高8位(AH)的內(nèi)容和低8位(AL)的內(nèi)容兩部分,對于與AL有關(guān)的字節(jié)操作指令,AH的內(nèi)容將不受影響。對字節(jié)操作指令,標志位的設(shè)置也按相應(yīng)字節(jié)的結(jié)果考慮,例如表3.14第5條指令執(zhí)行后,AL的內(nèi)容為A5H,此時的SF=1而不是0。
TEST指令與AND指令的區(qū)別類似于CMP指令與SUB指令的區(qū)別。TEST指令的結(jié)果只體現(xiàn)在對標志位的影響上,并不改變原目的操作數(shù)的值。AND指令則不同,除對標志位有影響外,相與后的結(jié)果將取代目的操作數(shù)的原來值。3.2.4移位指令和循環(huán)移位指令
表3.15中給出了移位指令和循環(huán)移位指令的指令格式和功能說明。表3.15移位、循環(huán)移位指令格式與功能指令的功能是將DST所指出的操作數(shù)的各位左移或右移若干位,移位的次數(shù)由CNT確定。
指令中的目的操作數(shù)的尋址方式可以是除立即數(shù)外的各種尋址方式,但不能是段寄存器。CNT可以是立即數(shù)或寄存器CL。當(dāng)CNT為立即數(shù)時,其值只能為1;當(dāng)移位次數(shù)超過1時,CNT應(yīng)為寄存器CL,CL中的內(nèi)容為移位次數(shù)。
左移指令,即表中的SHL/SAL指令,移位時操作數(shù)的最低位將移入0,而最高位移入CF中;若左移若干位,那么CF中只保留最后一次移出的內(nèi)容。右移指令有兩種情況:①即表中的SHR指令,稱邏輯右移指令,移位時操作數(shù)的最高位將移入0,最低位移入CF中;②即表中的SAR指令,稱算術(shù)左移指令,移位時操作數(shù)的最高位移入的是它原來的值,即最高位保持不變,最低位同樣移入CF中。算術(shù)右移主要用于帶符號數(shù)的右移。同樣,若右移若干位,那么CF中只保留最后一次移出的內(nèi)容。
循環(huán)移位指令,即表中的后面4條指令,它們是將操作數(shù)本身或者操作數(shù)與CF一起構(gòu)成一個環(huán)形移位,移位的次數(shù)也由CNT確定。同樣,若移位若干次,CF中只保留最后一次移出的內(nèi)容。移位指令與循環(huán)移位指令對標志位的影響是不一樣的,移位指令將影響除AF外的各標志位,AF的內(nèi)容為不定。循環(huán)移位指令只影響標志位CF和OF。不論是移位指令還是循環(huán)移位指令,只有當(dāng)CNT的值為1時,OF才有意義,并且OF的設(shè)置規(guī)則為:當(dāng)操作數(shù)的高位在移位前后不發(fā)生變化時OF=0,否則OF=1。例如,可以有如下的移位指令:
SHRAX,1 ;將AX的內(nèi)容右移1位,最高位補0
SALAL,CL ;將AL的內(nèi)容左移CL中指出的位數(shù),且每次移位最低位補0
ROLDAT1[SI],CL;將內(nèi)存某單元的內(nèi)容循環(huán)左移CL中所指的位數(shù)
例中的第3條指令的目的操作數(shù)的尋址方式為寄存器相對尋址,?DAT1是已定義的變量,該指令實現(xiàn)對有效地址EA=DAT1的偏移地址+(SI)所指單元的內(nèi)容循環(huán)左移,移位次數(shù)由CL中的內(nèi)容決定。3.2.5位測試指令
386及其后繼機型增加了本組指令。
1.?BT位測試指令
格式:BTDST,SRC
執(zhí)行操作:把目的操作數(shù)中右源操作數(shù)指定位的值(0或1)送往標志位CF。
2.?BTS位測試指令并置1指令
格式:BTSDST,SRC
執(zhí)行操作:把目的操作數(shù)中右源操作數(shù)指定位的值(0或1)送往標志位CF,并將目的操作數(shù)中的該位置1。
3.?BTR位測試指令并置0指令
格式:BTRDST,SRC
執(zhí)行操作:把目的操作數(shù)中右源操作數(shù)指定位的值(0或1)送往標志位CF,并將目的操作數(shù)中的該位置0。
4.?BTC位測試指令并取反指令
格式:BTCDST,SRC
執(zhí)行操作:把目的操作數(shù)中右源操作數(shù)指定位的值(0或1)送往標志位CF,并將目的操作數(shù)中的該位取反。
5.?BSF正向位掃描指令
格式:BSFREG,SRC
執(zhí)行操作:從位0開始,自右向左掃描源操作數(shù),檢測第一個為1的位。如遇到第一個為1的位,則將該位的位位置裝入目的寄存器REG,并將ZF置0;若源操作數(shù)為0,則目的寄存器無定義,并將ZF置1。
6.?BSR反向位掃描指令
格式:BSRREG,SRC
執(zhí)行操作:從最高有效位開始,自左向右掃描源操作數(shù),檢測第一個為1的位。如遇到第一個為1的位,則將該位的位位置裝入目的寄存器REG,并將ZF置0;若源操作數(shù)為0,則目的寄存器無定義,并將ZF置1。3.2.6處理器控制指令與標志處理指令
表3.16給出了處理器控制指令與標志處理指令的格式及主要功能說明。表中的前7條指令分別是對狀態(tài)寄存器的CF、DF、IF置位、復(fù)位或取反的。這些指令功能比較簡單,這里不作更多說明。表3.16控制指令與標志處理指令格式及功能
1.?NOP指令
CPU執(zhí)行該指令時,不完成任何具體功能,也不影響標志位,只占用機器的3個時鐘周期。所以,NOP指令也稱為空操作指令。
2.?HLT指令
該指令使CPU進入暫停狀態(tài)。只有當(dāng)下面三種情況之一發(fā)生時,CPU才退出暫停狀態(tài):CPU的復(fù)位輸入端RESET線上有復(fù)位信號;非屏蔽中斷請求輸入端NMI線上出現(xiàn)請求信號;可屏蔽中斷輸入端INTR線上出現(xiàn)了請求信號且標志寄存器的中斷標志IF=1。
3.?WAIT指令
CPU執(zhí)行該指令時,測試CPU的引線。當(dāng)線為高電平時,CPU進入等待狀態(tài),且每隔3個時鐘周期對的狀態(tài)進行一次測試,直到引線出現(xiàn)低電平時,CPU退出等待,順序執(zhí)行下一條指令。
4.?LOCK指令
這是一條前綴指令,可放在任何指令的前面,使得相應(yīng)指令執(zhí)行時,總線被鎖定,使別的主設(shè)備不能使用總線。本指令不影響標志位。
5.?ESC指令
指令格式:ESCDATA,SRC
這條指令主要用于CPU與外部處理器(如協(xié)處理器8087)配合工作。CPU執(zhí)行該指令時,相應(yīng)的協(xié)處理器應(yīng)配合工作。SRC將指出送給協(xié)處理器的操作數(shù)。DATA是一個事先規(guī)定的6位立即數(shù),執(zhí)行ESC指令時,利用這6位數(shù)控制外部處理器完成預(yù)定操作。
表3.16中的后兩條指令主要用于多處理器配合工作,相關(guān)內(nèi)容超出本書知識范疇,不作詳細說明。
3.3匯編語言程序設(shè)計的基本方法
3.3.1匯編語言程序設(shè)計的基本步驟
1.分析問題
首先必須明確求解問題的意義和任務(wù),明確所要解決的問題的物理過程及其工作狀態(tài)、輸入信息的形式和種類、要求輸出什么樣的信息,等等。經(jīng)過詳細了解和分析,將一個實際問題轉(zhuǎn)化為一個計算機可以處理的問題。
2.確定算法
所謂算法,簡單地說就是計算機能夠?qū)崿F(xiàn)的有限的解題步驟。我們知道,計算機只能進行最基本的算術(shù)運算和邏輯運算,要完成較為復(fù)雜的運算和控制操作,必須選擇合適的算法,這是正確編程的基礎(chǔ)。
算法可以用自然語言、類程序設(shè)計語言(也稱半自然語言)或流程框圖來描述。本書將主要采用流程圖描述。圖3.7給出了流程圖中較為通用的幾種符號。
(1)起始和終止框是表示程序開始和結(jié)束的符號,它總是在一個流程框圖的開頭與結(jié)尾處。圖3.7流程圖通用的幾種符號
(2)執(zhí)行框用來表示完成的某項功能,它可以是一條指令或一段程序,無論哪種情況,該框只能有一個入口和一個出口。
(3)判斷框是用來表示程序在此處要根據(jù)不同情況形成分支,框內(nèi)需寫明比較的條件,此框有一個入口,兩個出口。
(4)連接符是用來連接兩個流程框圖的符號,圓形符號內(nèi)可寫入標識符,不同流程框圖中連接符中的標識符相同的各點將連接在一起。
3.編寫程序
編寫程序是采用程序設(shè)計語言來實現(xiàn)上面已確定的算法。此過程有些書上則稱為編碼。本書所介紹的是采用匯編語言編寫程序。采用匯編語言編寫程序應(yīng)注意以下幾個問題:
(1)必須詳細了解所用CPU的編程模型、指令系統(tǒng)、尋址方式及有關(guān)偽指令;
(2)必須進行存儲空間和工作單元的合理分配;
(3)多次使用的程序段可采用子程序或宏指令;
(4)盡可能用標號或變量來代替絕對地址和常數(shù)。
4.程序的檢驗
程序編好以后,必須經(jīng)過書面的檢查和上機調(diào)試,以便說明程序是否正確。檢驗時,應(yīng)預(yù)先選擇典型數(shù)據(jù),檢查是否可以得到預(yù)期結(jié)果。
5.編寫說明文件
一個完整的軟件必須有相應(yīng)的說明文件,這不僅便于用戶使用,也便于對程序的維護和擴充。說明文件主要應(yīng)包括程序的功能和使用方法,程序的基本結(jié)構(gòu)和所采用的主要算法以及程序的必要說明和注意事項等。3.3.2IBMPC匯編語言源程序的完整結(jié)構(gòu)及偽指令
IBMPC匯編語言源程序由若干個段(Segment)組成。這意味著源程序編寫時,要把程序中出現(xiàn)的數(shù)據(jù)、程序指令以及程序中用到的堆棧等都必須分別寫入不同的段中,在源程序匯編成目的程序加載到內(nèi)存時也是按段結(jié)構(gòu)進行的。
本節(jié)討論的偽指令在源程序編寫時能清晰地定義各種段,在匯編時能告訴匯編程序哪些段屬于指令代碼段,哪些段屬于數(shù)據(jù)段,哪些段屬于堆棧段,以及如何分配內(nèi)存空間。下面首先介紹構(gòu)成完整程序的有關(guān)偽指令。
1.段定義偽指令
一對偽指令分別用于定義段的開始和結(jié)尾,助記符分別為SEGMENT和ENDS。
格式:
段名SEGMENT[定位類型][組合類型][使用類型][‘類別’]
…;指令語句或偽指令語句
段名ENDS
1)段名
段名是標識符,是所定義的段的名稱。段名除了有段地址和偏移地址的屬性以外,還有定位類型、組合類型和類別三個屬性。定位類型、組合類型和類別是可選的。SEGMENT到ENDS之間的部分則定義該段的具體內(nèi)容。
2)定位類型
定位類型表示對段的起始邊界的要求,其類型有PAGE、PARA、WORD、BYTE等4種。指定段的起始地址應(yīng)分別可以被256、16、2、1整除,分別稱為以頁、節(jié)、字、字節(jié)為邊界。例如,若定位類型為WORD類型,那么,該段的起始地址應(yīng)能被2整除。定位類型的缺省項(默認類型)是PARA。
3)組合類型
組合類型說明程序連接時的不同模塊中的同名段的合并方式,它們可以是:
PRIVATE:該段為私有段,在連接時不與其他模塊中的同名段合并。
PUBLIC:該段連接時和不同模塊中的同名段連接而形成一個段,其連接次序由連接命令指定。每一分段都從小段的邊界開始,因此各模塊的原有段之間可能存在間隙。
COMMON:該段連接時可以把不同模塊中的同名段重疊而形成一個段,各同名段有相同的起始地址,所以會產(chǎn)生覆蓋。COMMON的連接長度是各分段中的最大長度,重疊部分的內(nèi)容取決于排在最后的段的內(nèi)容。
ATexpression:使段地址是表達式所計算的16位值,不能用來指定代碼段。
MEMORY:同PUBLIC。
STACK:該段連接時和不同模塊中的同名段連接而形成一個堆棧段,其連接次序由連接命令指定,段的長度為各原有段的總和。各原有段之間無間隙,而且棧頂可自動指向連接后形成的大堆棧段的棧頂。
組合類型缺省項為PRIVATE。
4)使用類型
只適用于386及其后繼機型,用來說明使用16位尋址方式還是32位尋址方式??梢允牵?/p>
USE16使用16位尋址方式
USE32使用32位尋址方式
當(dāng)使用16位尋址方式時,段長不超過64KB,地址形式是16位段地址和16位偏移地址。當(dāng)使用32位尋址方式時,段長可達4GB,地址形式是16位段地址和32位偏移地址。在實模式下,應(yīng)使用USE16。
使用類型的缺省項為USE16。
5)‘類別’
‘類別’給出在連接時組成段組的類型名。類別說明并不能把相同類別的段合并起來,但在連接后形成的裝入模塊中,可以把它們的位置靠在一起。
段定義時,段名是不能省略的,定位類型、組合類型和‘類別’均可省略,若不省略,它們的書寫順序不能隨意更改。
段定義必須以ENDS偽指令結(jié)束,在同一個段定義中,SEGMENT與ENDS前的段名必須一致。同一個程序中可以出現(xiàn)多個段,這是通過多次段定義實現(xiàn)的。
IBMPC匯編語言源程序的典型段結(jié)構(gòu)如下:上面程序中有4個段,即堆棧段(STACK)、數(shù)據(jù)段(DATA)、代碼段(CODE)和附加段(EXTERN)。代碼段是程序的主體部分,由一系列指令組成,實現(xiàn)程序的基本功能。不是所有程序都必須有4個段,有些程序
溫馨提示
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年漢中市漢臺區(qū)建國幼兒園招聘備考題庫(2人)及1套參考答案詳解
- 2025云南昆一中教育集團學(xué)貫中學(xué)招聘1人備考題庫有答案詳解
- 2026山東濟南市屬事業(yè)單位招聘初級綜合類崗位人員111人備考題庫及答案詳解1套
- 2026四川涼山州雷波縣糧油貿(mào)易總公司面向社會招聘6人備考題庫有答案詳解
- 2026安徽淮南市壽縣楚通公共交通有限公司就業(yè)見習(xí)招聘2人備考題庫帶答案詳解
- 2026江西贛州市招聘章貢區(qū)商會工作人員1人備考題庫及參考答案詳解1套
- 2026年度濟南市歷下區(qū)所屬事業(yè)單位公開招聘初級綜合類崗位人員備考題庫及1套參考答案詳解
- 2026四川成都文化旅游發(fā)展集團有限責(zé)任公司下屬企業(yè)招聘項目執(zhí)行崗等崗位1人備考題庫及一套完整答案詳解
- 2026中國農(nóng)業(yè)科學(xué)院第一批招聘359人備考題庫及參考答案詳解1套
- 2026云南紅河老兵聯(lián)綜合保障服務(wù)有限公司保安員招聘1人備考題庫及答案詳解(考點梳理)
- 高一英語作業(yè)反饋與改進計劃
- 高標準農(nóng)田建設(shè)項目驗收技術(shù)方案
- 醫(yī)療器器械年終總結(jié)
- 六年級語文下冊《快樂讀書吧》必背知識點
- 鋼架樓梯安裝合同范例
- 浙江省杭州市富陽區(qū)2023-2024學(xué)年四年級上學(xué)期語文期末試卷
- 環(huán)境影響評估投標方案(技術(shù)方案)
- JTG-T3651-2022公路鋼結(jié)構(gòu)橋梁制造和安裝施工規(guī)范
- 河南中美鋁業(yè)有限公司登封市陳樓鋁土礦礦山地質(zhì)環(huán)境保護與土地復(fù)墾方案
- 海南省定安縣龍河鎮(zhèn)大嶺建筑用花崗巖礦山 環(huán)評報告
- 大學(xué)生畢業(yè)論文寫作教程全套教學(xué)課件
評論
0/150
提交評論