《單片機(jī)原理與應(yīng)用》課件1第3章_第1頁
《單片機(jī)原理與應(yīng)用》課件1第3章_第2頁
《單片機(jī)原理與應(yīng)用》課件1第3章_第3頁
《單片機(jī)原理與應(yīng)用》課件1第3章_第4頁
《單片機(jī)原理與應(yīng)用》課件1第3章_第5頁
已閱讀5頁,還剩177頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第三章MCS-51指令系統(tǒng)3.1匯編語言3.2指令系統(tǒng)思考練習(xí)題

3.1匯編語言

CPU是由各種功能電路組成的一個(gè)復(fù)雜的系統(tǒng),可以實(shí)現(xiàn)各種算術(shù)運(yùn)算和邏輯運(yùn)算功能。要使CPU按照人的要求完成一項(xiàng)工作,就是使CPU各功能電路按順序執(zhí)行各種操作,也就是執(zhí)行一條條的指令。人們編制的這些指令操作序列就叫做程序。CPU按照人們編制的程序,使內(nèi)部電路順序工作,完成指定的任務(wù)。

CPU能直接識(shí)別和執(zhí)行的是機(jī)器語言。機(jī)器語言用二進(jìn)制編碼表示每一條指令。80C51單片機(jī)的機(jī)器語言用8位二進(jìn)制碼表示指令(稱為一個(gè)字節(jié))。CPU讀取指令的二進(jìn)制碼并轉(zhuǎn)換為內(nèi)部的電平,協(xié)調(diào)內(nèi)部電路的工作。例如,要完成“1+2”的加法操作,80C51用機(jī)器碼指令編程為:

0111010000000001 把1送到累加器A中

0010010000000010 A中的內(nèi)容加2,結(jié)果仍放到A中

80C51指令有單字節(jié)、雙字節(jié)或三字節(jié)形式。上面完成“1+2”的加法操作是兩條雙字節(jié)指令。一般為了書寫和記憶方便,可以采用十六進(jìn)制,則以上兩條指令可以寫成:

7401H

2402H可以看到,用機(jī)器語言編寫的程序不容易記憶,而且容易出錯(cuò)。為了克服上述缺點(diǎn),可以采用含有一定意義的符號(hào)來代替機(jī)器語言,即指令助記符。這種指令助記符一般是有關(guān)的英文單詞的縮寫,這就形成了另外一種程序語言——匯編語言。

上面的程序用匯編語言表示為:

MOVA,#01H

ADDA,#02H這里,用MOVA,#01H代替7401H。其中,74H是80C51的指令碼,表示一個(gè)數(shù)據(jù)送到累加器A的操作,用指令助記符MOVA來表示;01H是要傳送的數(shù)據(jù)。同樣,ADDA,#02H代替2402H,24H是指令碼,表示累加器和數(shù)據(jù)的加法操作,用指令助記符ADDA表示;02H是要加的數(shù)據(jù)。

可以看出,匯編語言是用助記符、符號(hào)和數(shù)字等來表示各種指令的程序語言,與機(jī)器語言有一一對(duì)應(yīng)的關(guān)系,容易理解和記憶,修改和查找錯(cuò)誤也方便。但是它和機(jī)器語言一樣,每一種計(jì)算機(jī)都有自己的匯編語言,與計(jì)算機(jī)內(nèi)部的硬件結(jié)構(gòu)和組成密切相關(guān)。不同的計(jì)算機(jī)其匯編語言也是不同的,因此它不如高級(jí)語言那樣通用。3.1.1MCS-51指令格式

80C51匯編語言指令一般由標(biāo)號(hào)段、操作碼助記符字段、操作數(shù)字段和注釋等四部分組成。指令格式為

[標(biāo)號(hào):]操作碼[目的操作數(shù)][,源操作數(shù)][;注釋]

例如DA:MOVA,#01H;01送給累加器A

第一部分為標(biāo)號(hào)段(可以沒有),是該條指令的符號(hào)地址,它并非每條指令所必需的,

主要是為了方便軟件的編制。標(biāo)號(hào)以字母開始,后跟1~8個(gè)字母或數(shù)字,并以冒號(hào)“:”結(jié)尾。操作碼部分規(guī)定了指令的操作功能,即說明了指令的操作性質(zhì)。操作碼是指令中唯一不能缺少的部分。上例中的操作碼是MOV,表示指令進(jìn)行的送數(shù)操作。操作碼一般由2~5個(gè)英文字母表示,例如ADD、JB、LCALL等。

操作數(shù)指出了指令的操作對(duì)象。操作數(shù)可以是一個(gè)具體的數(shù)據(jù),也可以是存放數(shù)據(jù)的單元地址,即在指令執(zhí)行時(shí)從指定的地址取出操作數(shù),甚至是符號(hào)常量或符號(hào)地址等。根據(jù)不同的指令,可以有1個(gè)、2個(gè)、3個(gè)或根本沒有操作數(shù)。操作數(shù)與操作碼之間至少有一個(gè)空格,也可以有多個(gè)空格;各操作數(shù)之間用逗號(hào)分開。操作數(shù)部分指出了參與操作的數(shù)據(jù)來源和操作結(jié)果存放的目的單元。上例中A是目的操作數(shù)(有些指令省略),也是操作結(jié)果的存放地;#01H是源操作數(shù)(有些指令省略)。

編寫程序時(shí)可以加注釋,以分號(hào)“;”開始,表示對(duì)該行指令或程序段的說明,用于增加程序的易讀性。注釋應(yīng)在一行內(nèi)寫完,換行則需要另外以分號(hào)開始。

標(biāo)號(hào)段和注釋段在匯編時(shí)是不參加匯編的,它只是為了編程方便,幫助閱讀和理解程序而添加的。

具體的指令書寫方法可參看附錄中的指令表,指令表中所使用的符號(hào)其意義說明如下:但應(yīng)注意,凡指令表上標(biāo)明符號(hào)的地方,在使用時(shí)必須根據(jù)符號(hào)要求選用具體數(shù)值。不允許在程序中出現(xiàn)MOVA,Rn這種寫法,因?yàn)镽n只是一種代號(hào),到底使用哪一個(gè)R,必須按事先選定的值寫上。例如選用R1或R2,則寫成MOVA,R1或MOVA,R2。

操作數(shù)可以是數(shù)據(jù),也可以是地址。當(dāng)操作數(shù)是指令中給出的數(shù)據(jù)時(shí),則稱為立即數(shù),它有8位和16位二進(jìn)制數(shù)兩種。在助記符的數(shù)字前加“#”來標(biāo)記其是立即數(shù),常用符號(hào)“#data”表示。對(duì)同樣的數(shù)據(jù)“data”,若前面加“#”即表示立即數(shù),不加“#”則表示直接地址單元。對(duì)選定的工作寄存器R0~R7,只有R0和R1既能存放數(shù)據(jù)又能存放地址,若R0、R1前面加“@”,則表示R0、R1中存放地址;若不加“@”則表示存放數(shù)據(jù)。同樣,若DPTR前面加“@”則表示數(shù)據(jù)指針寄存器存放16位地址,否則表示存放16位數(shù)據(jù)。

應(yīng)注意一條指令必須占用一行,不要在一行中寫兩條以上指令。

8051單片機(jī)是MCS-51單片機(jī)系列中最早的一個(gè)成員,但它和MCS-51系列的其它成員一樣,都使用MCS-51指令系統(tǒng)。MCS-5l指令系統(tǒng)共有111條指令,根據(jù)指令所占字節(jié)多少劃分,單字節(jié)指令49條,雙字節(jié)指令45條,三字節(jié)指令17條;根據(jù)每條指令執(zhí)行所需時(shí)間劃分,單機(jī)器周期指令64條,雙機(jī)器周期指令45條,四機(jī)器周期指令2條(乘、除法指令)。這樣,根據(jù)指令所占字節(jié)及執(zhí)行所需時(shí)間不同,MCS-51指令系統(tǒng)共有6種情況:?jiǎn)沃芷趩巫止?jié)、單周期雙字節(jié)、雙周期單字節(jié)、雙周期雙字節(jié)、雙周期三字節(jié)、四周期單字節(jié)。單片機(jī)的指令是完成一定操作功能與尋址方式的代碼或助記符,每條指令的字節(jié)數(shù)就是指為能表達(dá)該指令操作內(nèi)容所需代碼的字節(jié)數(shù),不同的操作或不同的尋址方式所需字節(jié)數(shù)也不同。

1.單字節(jié)指令

單字節(jié)指令中的8位二進(jìn)制代碼既包含操作碼信息,也包含操作數(shù)信息,分為以下兩種情況:

(1)操作數(shù)固定,只需一個(gè)字節(jié)即可完整明確地表示出指令的功能。在指令碼中隱含著對(duì)某個(gè)寄存器的操作。例如,數(shù)據(jù)指針DPTR加1指令:INCDPTR。由于操作內(nèi)容和對(duì)象DPTR寄存器唯一,所以只用8位二進(jìn)制代碼就可以表示,其指令代碼為A3H,格式為10100011

(2)操作數(shù)在工作寄存器中,其尋址變化只需3位二進(jìn)制碼即可表示(一共有8個(gè)工作寄存器),此時(shí)操作碼占一字節(jié)中的5位,操作數(shù)占3位。指令碼中含有寄存器號(hào)。例如,工作寄存器向累加器A傳送數(shù)據(jù)指令:MOVA,Rn,其指令碼格式為

MOVA,Rn這一條指令表示要把Rn(n=0~7)中的內(nèi)容傳到累加器A,最右邊的3位r均可任意為0或1,因而能代表8種狀態(tài),剛好表示R0~R7這8個(gè)寄存器。這樣,與MOVA,Rn相對(duì)應(yīng)的機(jī)器碼為E8H~EFH(H代表十六進(jìn)制)。這時(shí)只要一個(gè)字節(jié)就可以表達(dá)清楚該指令的操作碼和操作數(shù),因而是單字節(jié)指令。十六進(jìn)制機(jī)器碼的使用,縮短了碼的長(zhǎng)度,方便書寫和閱讀,并加快了碼的輸入速度。同時(shí),一個(gè)字節(jié)剛好可以用兩個(gè)十六進(jìn)制字母代表,即一個(gè)十六進(jìn)制字母代表半個(gè)字節(jié),這是其它進(jìn)制所不能實(shí)現(xiàn)的。

2.雙字節(jié)指令

雙字節(jié)指令用一個(gè)字節(jié)表示操作碼,另一個(gè)字節(jié)表示操作數(shù)或操作數(shù)所在的地址。

MOVA,data這一指令表示要把一個(gè)直接地址中的數(shù)據(jù)送到累加器A,看起來它和MOVA,Rn指令相似,但由于直接地址是一個(gè)8位地址,它不可能像后一指令編碼那樣利用后幾位來表示,必須另用一個(gè)字節(jié)專門表示直接地址,它的指令編碼為這樣,它就成為雙字節(jié)指令,用十六進(jìn)制機(jī)器碼表示為E5data。

3.三字節(jié)指令

三字節(jié)指令中,一個(gè)字節(jié)為操作碼,兩個(gè)字節(jié)為操作數(shù)。

例如,MOVdata1,data2這一指令表示要把一個(gè)直接地址中的數(shù)據(jù)送到另一個(gè)直接地址單元中去。由于這兩個(gè)直接地址都為8位地址,所以該指令需3字節(jié)表示,它的編碼為

用十六進(jìn)制機(jī)器碼表示為E5data1data2。由于每條指令所占用字節(jié)數(shù)不同,所以每執(zhí)行一條指令增加的PC值是不同的,單字節(jié)指令加1,雙字節(jié)指令加2,三字節(jié)指令加3。

從指令編碼中可以看出,凡在操作數(shù)中有Rn(n=0~7)或Ri(i=0~1)、累加器A等的指令都比用直接地址代替它們的指令少一個(gè)字節(jié),因?yàn)镽n和Ri的地址和操作碼合用一個(gè)字節(jié),累加器A等已隱含在操作碼中。

執(zhí)行每條指令所需的機(jī)器周期數(shù),既取決于每條指令所含的字節(jié)數(shù),也取決于指令在執(zhí)行過程中的微操作。很明顯,由于單片機(jī)CPU在每個(gè)機(jī)器周期最多只能進(jìn)行兩次讀操作,每次一個(gè)字節(jié),所以單字節(jié)、雙字節(jié)指令均可在一個(gè)機(jī)器周期內(nèi)完成,但三字節(jié)指令卻不可能在一個(gè)機(jī)器周期內(nèi)完成。另外,單字節(jié)指令可以但不是必須在一個(gè)機(jī)器周期內(nèi)完成,也可以在兩個(gè)機(jī)器周期內(nèi)完成,甚至需4個(gè)機(jī)器周期才能完成(如乘、除法指令)。如MOVXA,@R0是一條單字節(jié)指令,但它必須在第一機(jī)器周期內(nèi)讀操作碼及R0的值;在第二機(jī)器周期才能讀R0所指單元的值,然后送入累加器A。而MOVA,R0卻只需一個(gè)機(jī)器周期就能完成,因?yàn)樗诘谝粋€(gè)機(jī)器周期就能讀得操作碼及R0的值,即可把R0的值送入累加器A。因此,前者需兩個(gè)機(jī)器周期,后者僅需一個(gè)機(jī)器周期。3.1.2指令操作過程

如果要求計(jì)算機(jī)按照人的意圖辦事,則需要設(shè)法讓人與計(jì)算機(jī)對(duì)話,并聽從人的指揮。程序設(shè)計(jì)語言是實(shí)現(xiàn)人機(jī)交換信息(對(duì)話)的最基本工具,可分為機(jī)器語言、匯編語言和高級(jí)語言。機(jī)器語言用二進(jìn)制編碼表示每條指令,它是計(jì)算機(jī)能直接識(shí)別和執(zhí)行的語言。用機(jī)器語言編寫的程序稱為機(jī)器語言程序或指令程序(機(jī)器碼程序)。機(jī)器只能直接識(shí)別和執(zhí)行這種由0和1編碼組成的機(jī)器碼程序,又稱其為目標(biāo)程序。8051單片機(jī)是8位機(jī),其機(jī)器語言以8位二進(jìn)制碼為單位(稱為一個(gè)字節(jié))。由匯編語言編寫的程序稱為源程序。但源程序不能被計(jì)算機(jī)硬件直接識(shí)別和執(zhí)行,必須通過匯編把它變成機(jī)器語言。經(jīng)過匯編得到的機(jī)器語言形式的程序稱為目標(biāo)程序。

指令字節(jié)越多,所占內(nèi)存單元越多,但執(zhí)行時(shí)間的長(zhǎng)短只取決于執(zhí)行該指令需要多少個(gè)機(jī)器周期。單片機(jī)在工作時(shí),按時(shí)鐘電路產(chǎn)生的工作節(jié)拍,CPU順序執(zhí)行各種操作,即一步步地執(zhí)行一條條的指令。我們知道,單片機(jī)中由電路組成的各個(gè)功能單元協(xié)調(diào)工作,它只能識(shí)別高低電平,也就是二進(jìn)制數(shù)0和1。這樣,無論我們用高級(jí)語言、匯編語言還是機(jī)器語言,最后它們都要變成為表示高低電平的0和1,并存儲(chǔ)在存儲(chǔ)單元中,由指令計(jì)數(shù)器控制順序取數(shù)(80C51為8位單片機(jī),以字節(jié)為單位),并按取出的二進(jìn)制數(shù)使相應(yīng)的內(nèi)部各個(gè)功能電路動(dòng)作,完成所要求的任務(wù)。圖3-1是一個(gè)單字節(jié)單周期指令的執(zhí)行時(shí)序,例如我們要求CPU執(zhí)行INCA這條指令,它的指令代碼為00000100,即04H,在存儲(chǔ)器當(dāng)前位置存儲(chǔ)的就是04H??梢钥吹?,在單片機(jī)振蕩電路產(chǎn)生的時(shí)鐘脈沖的協(xié)調(diào)下,地址鎖存信號(hào)ALE在一個(gè)機(jī)器周期內(nèi)兩次有效:第一次是在S1P2和S2P1期間,第二次是在S4P2和S5P1期間。作為單周期指令,在S1P2時(shí)CPU通過8位數(shù)據(jù)總線讀取存儲(chǔ)器當(dāng)前位置數(shù)據(jù)04H并鎖存于指令寄存器內(nèi),第二次ALE有效讀操作無效。單片機(jī)內(nèi)部的指令譯碼器電路對(duì)指令寄存器內(nèi)存儲(chǔ)的04H進(jìn)行譯碼操作,識(shí)別為對(duì)累加器A內(nèi)的內(nèi)容進(jìn)行加1操作,再存回累加器A中。這樣就控制累加器A進(jìn)行相應(yīng)的操作,完成所要求的任務(wù)。如果程序存儲(chǔ)器當(dāng)前位置存儲(chǔ)的數(shù)據(jù)不是04H,而是09H,則指令寄存器內(nèi)鎖存的是09H,而不是04H,指令譯碼電路譯碼的結(jié)果是對(duì)通用寄存器R1的內(nèi)容進(jìn)行加1操作,再存回R1中,從而控制相應(yīng)的電路工作。它的匯編指令格式為INCR1。圖3-1單字節(jié)單周期指令

例3-1

指令如下:

?MOVA,#07H

這是一條雙字節(jié)指令,機(jī)器碼是74H07H,完成的是把立即數(shù)07H送到累加器A中的操作。其中74H是操作碼,07H是操作數(shù)。假設(shè)上面指令的機(jī)器碼存放在程序存儲(chǔ)器地址為1000H和1001H的單元中,其操作過程主要分兩個(gè)階段完成。第一階段為取操作碼并譯碼控制相關(guān)電路工作,稱為取指階段,如圖3-2所示。執(zhí)行過程如下:

①程序計(jì)數(shù)器PC指向地址1000H,表示由此地址開始去取指令。

②將1000H送地址寄存器AR。③將1000+1=1001H送給PC,指向下次讀存儲(chǔ)單元時(shí)的地址。

④地址寄存器中的地址通過地址總線AB送至地址譯碼器AD,選中1000H單元。

⑤CPU發(fā)讀命令送至存儲(chǔ)器。

⑥將存儲(chǔ)單元1000H中的內(nèi)容經(jīng)數(shù)據(jù)總線送至數(shù)據(jù)寄存器DR。

⑦因?yàn)槿≈鸽A段得到的是指令操作碼,所以DR內(nèi)容送至指令寄存器IR。

⑧指令譯碼后轉(zhuǎn)換為控制電位和脈沖,控制單片機(jī)各相關(guān)部件完成指令功能。

取操作數(shù)的信息流程如圖3-2所示。圖3-2指令取指階段的信息流程指令取出后,就轉(zhuǎn)入指令的執(zhí)行階段,取操作數(shù)并將操作數(shù)送至累加器A,其工作流程如圖3-3所示。操作過程如下:

①將PC=1001H送地址寄存器AR。

②將1001+1=1002H送給PC,指向下次讀存儲(chǔ)單元時(shí)的地址。

③地址寄存器中的地址通過地址總線AB送至地址譯碼器AD,選中1001H單元。

④CPU發(fā)出讀命令送至存儲(chǔ)器。

⑤將存儲(chǔ)單元1001H中的內(nèi)容經(jīng)數(shù)據(jù)總線送至數(shù)據(jù)寄存器DR。⑥因?yàn)槿?shù)階段得到的是操作數(shù),所以DR內(nèi)容(這里是07H)送至累加器A。

至此,MOVA,#07H指令執(zhí)行完畢。

單字節(jié)雙周期、雙字節(jié)單周期、雙字節(jié)雙周期等指令的執(zhí)行過程類似,都是在時(shí)鐘電路的控制下,由單片機(jī)內(nèi)部各功能電路對(duì)存儲(chǔ)器存儲(chǔ)的二進(jìn)制代碼進(jìn)行相應(yīng)的操作。圖3-3取指令操作數(shù)及執(zhí)行信息流程要使計(jì)算機(jī)按照人的思維完成一項(xiàng)工作,就必須讓CPU按順序執(zhí)行各種操作,即一步步地執(zhí)行一條條的指令,這些按人的要求編排的指令操作序列稱為程序,編寫程序的過程就叫做程序設(shè)計(jì)。

因此,人們根據(jù)單片機(jī)要完成的任務(wù)要求編寫相應(yīng)的程序。無論采用高級(jí)語言、匯編語言還是機(jī)器語言,程序都是以二進(jìn)制代碼的形式存于程序存儲(chǔ)器中的。如果是高級(jí)語言和匯編語言編寫的程序,則還要進(jìn)行匯編,將其變成機(jī)器語言程序。3.1.3尋址方式和尋址空間

尋址方式就是指令執(zhí)行時(shí)確定操作數(shù)或操作數(shù)地址的方式。指令中的操作數(shù)可以是具體數(shù)據(jù),也可以是寄存器名稱或存儲(chǔ)單元地址。從表面上看,用具體數(shù)據(jù)比用寄存器名稱或地址更加簡(jiǎn)單明了,但采用具體數(shù)據(jù)作為操作數(shù)指令只能對(duì)一個(gè)數(shù)進(jìn)行操作,而將寄存器名稱作為操作數(shù)的指令使用起來更加靈活。只要給寄存器賦以不同的數(shù),就能對(duì)不同的數(shù)進(jìn)行操作。這一點(diǎn)只有在使用指令之后,才能逐漸體會(huì)到。

一般來說,尋址方式越多,單片機(jī)的尋址能力就越強(qiáng),用戶使用就越方便,但是指令系統(tǒng)也就越復(fù)雜。根據(jù)指令操作的需要,計(jì)算機(jī)一般提供多種尋址方式。MCS-51指令系統(tǒng)有以下7種尋址方式。

1.立即尋址

在這種尋址方式中,存儲(chǔ)在程序存儲(chǔ)器中、跟在操作碼后面的一個(gè)字節(jié)或兩個(gè)字節(jié)就是實(shí)際操作數(shù)。該操作數(shù)直接參與操作,所以又稱為立即數(shù),用符號(hào)“#”表示,以區(qū)別于直接地址。指令中的立即數(shù)有8位立即數(shù)#data和16位立即數(shù)#data16。由于立即數(shù)是一個(gè)常數(shù),不是物理空間,所以立即數(shù)只能作為源操作數(shù),不能作為目的操作數(shù)使用。

例3-2

指令如下:

??MOVA,#100

該指令功能為送十進(jìn)制數(shù)100到累加器A中,十進(jìn)制數(shù)100也可以用十六進(jìn)制數(shù)表示為64H。

當(dāng)向16位數(shù)據(jù)指針DPTR送數(shù)時(shí),操作數(shù)也為雙字節(jié),高字節(jié)送DPH,低字節(jié)送DPL。

例3-3指令如下:

MOVDPTR,#2000H

這是一個(gè)三字節(jié)指令,指令代碼為90H20H00H。其中第一個(gè)字節(jié)為操作碼,第二、三字節(jié)為操作數(shù)。指令執(zhí)行結(jié)果是向DPTR送立即數(shù)2000H,且DPH=20H,DPL=00H。

2.直接尋址

直接尋址是指在指令中包含了操作數(shù)的8位地址。該地址直接給出了參加運(yùn)算或傳送的單元或位,通過它可以訪問內(nèi)部RAM單元、位地址空間以及特殊功能寄存器SFR,且SFR和位地址空間只能用直接尋址方式來訪問。對(duì)于特殊功能寄存器,既可以使用它們的地址,也可以使用它們的名字。

例3-4

指令如下:

??MOVA,69H;(69H)→A

這條指令把內(nèi)部存儲(chǔ)器69H單元的內(nèi)容送入累加器A中,是雙字節(jié)指令,機(jī)器碼為E5H69H,尋址空間范圍是片內(nèi)RAM128字節(jié)和特殊功能寄存器。

3.寄存器尋址

寄存器尋址是指指定某一可尋址的寄存器的內(nèi)容為操作數(shù)。對(duì)累加器A、通用寄存器B、數(shù)據(jù)指針寄存器DPTR和進(jìn)位位C來說,其尋址時(shí)具體的寄存器已隱含在操作碼中,而對(duì)通用的8個(gè)工作寄存器R0~R7,可用PSW中的RSl、RS0來選擇寄存器組,再用操作碼中的低三位來確定是組內(nèi)哪一個(gè)寄存器,達(dá)到尋址的目的。

例3-5

指令如下:

??MOVA,R0;(R0)→A這條指令把R0中的內(nèi)容送入累加器A中,指令代碼形式為11101000,十六進(jìn)制數(shù)為E8H。

注意指令代碼中低三位為000,表示操作數(shù)為R0。如現(xiàn)在PSW中RSl、RS0分別為0、1,則可知現(xiàn)在的R0在第1組,則它的地址為08H。該指令的執(zhí)行過程如圖3-4所示。

圖3-4寄存器尋址方式執(zhí)行過程寄存器尋址的尋址空間范圍是工作寄存器R0~R7、A、B、C和DPTR。

4.寄存器間接尋址

寄存器間接尋址是將指令指定的寄存器內(nèi)容作為操作數(shù)所在的地址,對(duì)該地址單元中的內(nèi)容進(jìn)行操作的尋址方式。操作數(shù)所指定的寄存器中存放的不是操作數(shù)本身,而是操作數(shù)地址。可用來間接尋址的寄存器有:R0、R1、堆棧指針SP以及16位的數(shù)據(jù)指針DPTR,使用時(shí)操作數(shù)前面加符號(hào)“@”表示間接尋址。當(dāng)訪問片內(nèi)RAM或片外RAM低256字節(jié)時(shí),一般用R0或R1作間接尋址寄存器,在這類指令中,由操作碼的最低位指出所用的是R0還是R1。對(duì)于8051系列單片機(jī),可尋址內(nèi)部RAM中地址為00H~7FH的128個(gè)單元的內(nèi)容。對(duì)于8052系列單片機(jī),則為256個(gè)單元的內(nèi)容,而且,8052系列單片機(jī)的高128個(gè)字節(jié)RAM只能使用寄存器間接尋址方式訪問。另外,數(shù)據(jù)指針DPTR也可作為間接尋址寄存器,尋址外部數(shù)據(jù)存儲(chǔ)器的64?KB空間。

例3-6

指令如下:

??MOVA,@R1;((R1))→A該指令的功能是將當(dāng)前工作區(qū)內(nèi)以R1中的內(nèi)容作為地址的存儲(chǔ)單元中的數(shù)據(jù)送到累加器A中,其源操作數(shù)采用寄存器間接尋址方式,以R1作為地址指針。該指令的代碼形式為11100111,十六進(jìn)制為E7H,注意最低位為1,表示通用寄存器為R1?,F(xiàn)假設(shè)R1中存放30H,則該指令是將地址為30H的存儲(chǔ)單元中的內(nèi)容送到累加器A中,則指令的執(zhí)行過程如圖3-5所示。圖3-5寄存器間接尋址方式執(zhí)行過程如果用R0、R1作地址指針訪問片外RAM則需采用頁面尋址方式,因?yàn)镽0和R1都是8位寄存器,其直接訪問地址范圍為FFH,而擴(kuò)展外部數(shù)據(jù)存儲(chǔ)器范圍為64?KB,所以在這種工作情況下以256字節(jié)為一頁,共有256頁,頁面地址由P2口決定,頁內(nèi)地址由R0或R1的內(nèi)容決定。

例3-7

指令如下:

??MOVP2,#0A0H

MOVR0,#01H

MOVA,#10H

MOVX@R0,A上述指令執(zhí)行結(jié)果為:將累加器A中的數(shù)據(jù)10H傳送到頁面為A0H,頁內(nèi)地址為01H的外部數(shù)據(jù)存儲(chǔ)器地址單元,即送到外部數(shù)據(jù)存儲(chǔ)器A001H地址單元中。

寄存器間接尋址的尋址空間范圍是片內(nèi)低128字節(jié)(@R0,@R1,SP(僅PUSH、POP)),片外RAM(@R0,@R1,@DPTR)。

5.變址尋址(基址寄存器加變址寄存器)

變址尋址是以某個(gè)寄存器的內(nèi)容為基地址,然后在這個(gè)基地址的基礎(chǔ)上加上地址偏移量形成真正的操作數(shù)地址的尋址方式。MCS-51單片機(jī)以DPTR或PC為基址寄存器,以累加器A作為偏移量寄存器。這種尋址方式常用于查表操作。

例3-8

指令如下:

??MOVCA,@A+DPTR;((A)+(DPTR))→A

這條指令把DPTR中的內(nèi)容和A中的內(nèi)容相加作為16位程序存儲(chǔ)器地址,再把該地址的內(nèi)容送入累加器A中。假設(shè)累加器A的內(nèi)容為30H,DPTR的內(nèi)容為2100H,執(zhí)行該指令時(shí),把程序存儲(chǔ)器中地址為2100H+30H=2130H單元中的數(shù)據(jù)送入累加器A中。該指令的執(zhí)行過程如圖3-6所示。

變址尋址的尋址空間范圍是程序存儲(chǔ)器(@A+PC,@A+DPTR)。圖3-6基址寄存器加變址寄存器間接尋址方式執(zhí)行過程

6.相對(duì)尋址

相對(duì)尋址只出現(xiàn)在相對(duì)轉(zhuǎn)移指令中,是指將程序計(jì)數(shù)器PC中的當(dāng)前值(該當(dāng)前值為實(shí)際執(zhí)行完這條相對(duì)轉(zhuǎn)移指令后的字節(jié)地址)與指令給出的偏移量相加,其結(jié)果作為跳轉(zhuǎn)指令的轉(zhuǎn)移地址。指令第二字節(jié)給出的偏移量有正負(fù)號(hào),它在指令中以補(bǔ)碼形式給出,所轉(zhuǎn)移的范圍為-128~+127。一般將相對(duì)轉(zhuǎn)移指令操作碼所在的地址稱為源地址,轉(zhuǎn)移后的地址稱為目的地址。于是有:

目的地址=源地址+2(相對(duì)轉(zhuǎn)移指令字節(jié)數(shù))+rel

例3-9

指令如下:

??JC06H這條指令表示若進(jìn)位位C=0,則不跳轉(zhuǎn);若進(jìn)位位C=1,則以PC中的當(dāng)前值為基地址,加上偏移量06H后所得到的結(jié)果為該轉(zhuǎn)移指令的目的地址。

現(xiàn)假設(shè)該指令存放于2000H、2001H單元,且C=1,則開始取指令后,PC當(dāng)前值為2002H,對(duì)C進(jìn)行判斷后,PC內(nèi)容與偏移量06H相加,得到轉(zhuǎn)移目的地址2008H。故執(zhí)行完該指令后,PC中的值為2008H,程序?qū)?008H開始執(zhí)行。該指令的執(zhí)行過程如圖3-7所示。

在實(shí)際工作中,有時(shí)需根據(jù)已知的源地址(相對(duì)轉(zhuǎn)移指令操作碼所在地址)和目的地址計(jì)算偏移量rel?,F(xiàn)以兩字節(jié)相對(duì)轉(zhuǎn)移指令為例,討論偏移量rel的計(jì)算。圖3-7JC06H執(zhí)行示意圖正向跳轉(zhuǎn)時(shí):

rel?=?目的地址-源地址-2?=?地址差-2

反向跳轉(zhuǎn)時(shí),目的地址小于源地址,rel用負(fù)數(shù)的補(bǔ)碼表示:

rel?=?(目的地址-(源地址?+?2))補(bǔ)

? =?FFH-(源地址?+?2-目的地址)?+?1

=?100H-(源地址?+?2?-目的地址)

?

=?FEH-|地址差|

相對(duì)尋址的尋址空間范圍是程序存儲(chǔ)器256字節(jié)范圍(PC?+?偏移量)。

7.位尋址

位尋址是對(duì)片內(nèi)RAM的位尋址區(qū)和某些可位尋址的特殊功能寄存器進(jìn)行位操作時(shí)的尋址方式。采用位尋址方式的指令的操作數(shù)是8位二進(jìn)制數(shù)中的某一位。指令中給出的是位地址,即片內(nèi)RAM某一單元的一位。位地址在指令中用bit表示。位地址與直接尋址中的字節(jié)地址形式完全一樣,主要由操作碼來區(qū)分,使用時(shí)應(yīng)注意。

例3-10

指令如下:

??CLRbit

該指令完成對(duì)“bit”指定的地址單元清零的操作。

8051單片機(jī)片內(nèi)RAM有兩個(gè)區(qū)域可以位尋址:一個(gè)是20H~2FH的16個(gè)單元中的128bit,另一個(gè)是字節(jié)地址能被8整除的特殊功能寄存器。位尋址常采用以下兩種方式:

(1)直接使用位地址。20H~2FH的16個(gè)單元中的128?bit位地址分布是00H~7FH。如20H單元的0~7位位地址是00H~07H,而21H的0~7位位地址是08H~0FH,依此類推。

(2)對(duì)于特殊功能寄存器,可以直接用寄存器名字加位數(shù)表示,如PSW.3,P3.5等。

位尋址的尋址空間范圍是片內(nèi)RAM的20H~2FH字節(jié)地址、部分特殊功能寄存器。

MCS-51單片機(jī)的尋址方式有多種,但具體每條指令對(duì)哪一個(gè)存儲(chǔ)器空間進(jìn)行操作是由指令的操作碼和尋址方式確定的,可以總結(jié)出以下原則:

(1)對(duì)程序存儲(chǔ)器只能采用基址寄存器加變址寄存器間接尋址方式。

(2)對(duì)特殊功能寄存器空間只能采用直接尋址方式(SFR可以用符號(hào)表示),不能采用寄存器間接尋址方式。

(3)內(nèi)部數(shù)據(jù)存儲(chǔ)器高128字節(jié)只能采用寄存器間接尋址方式,不能采用直接尋址方式。

(4)內(nèi)部數(shù)據(jù)存儲(chǔ)器低128字節(jié)既能采用寄存器間接尋址方式,又能采用直接尋址方式。

(5)外部擴(kuò)展的數(shù)據(jù)存儲(chǔ)器只能采用MOVX指令訪問。 3.2指令系統(tǒng)

MCS-51單片機(jī)的匯編語言共使用42種操作碼來描述33種操作功能,操作碼助記符與尋址方式結(jié)合可得到111條指令,使用時(shí)只要熟悉42種操作碼助記符即可。這些指令按照功能劃分,可分為以下五類:數(shù)據(jù)傳送類、算術(shù)運(yùn)算類、邏輯運(yùn)算類、控制轉(zhuǎn)移類和位操作類。

下面分別介紹各類指令。3.2.1數(shù)據(jù)傳送類指令

CPU在進(jìn)行算術(shù)和邏輯操作時(shí),一般都要有操作數(shù),所以數(shù)據(jù)的傳送是一種最基本、最主要的操作。在應(yīng)用程序中,傳送指令占有很大的比例。數(shù)據(jù)傳送是否靈活、迅速,對(duì)整個(gè)程序的編寫和執(zhí)行都起著很大的作用。MCS-51具有極其豐富的數(shù)據(jù)傳送指令,方便用戶使用。數(shù)據(jù)傳送指令把源操作數(shù)傳送給目標(biāo)單元,源就是數(shù)據(jù)來源,目標(biāo)就是傳送的目的地。傳送指令用MOV、MOVX、MOVC、XCH、XCHD、PUSH、POP等助記符做為操作符。其中,MOV表示移動(dòng)(即傳送);XCH表示交換,交換是一種能雙向同時(shí)進(jìn)行的傳送;PUSH和POP則分別表示壓入和彈出,壓入和彈出也是一種傳送,只是傳送的一方位于堆棧而已。

數(shù)據(jù)傳送類指令有如下特點(diǎn):

(1)指令中有數(shù)據(jù)源地址和傳送數(shù)據(jù)目的地址,傳送方向?yàn)閺脑吹刂返侥康牡刂?,源地址中的?nèi)容保持不變。

(2)除累加器A為目的操作數(shù)指令外,數(shù)據(jù)傳送類指令不影響程序狀態(tài)寄存器(PSW)中的各標(biāo)志位。

根據(jù)傳送源和目標(biāo)的不同,傳送指令可以分為以下幾種類型:內(nèi)部數(shù)據(jù)傳送指令、外部數(shù)據(jù)存儲(chǔ)器數(shù)據(jù)傳送指令、程序存儲(chǔ)器數(shù)據(jù)傳送指令、堆棧操作指令和數(shù)據(jù)交換指令。

1.內(nèi)部數(shù)據(jù)傳送指令

(1)以累加器A為目的操作數(shù)的指令有4條,即4種尋址方式:這組指令的功能是把源操作數(shù)的內(nèi)容送入累加器A中,源操作數(shù)的內(nèi)容不發(fā)生改變。源操作數(shù)有寄存器尋址、直接尋址、寄存器間接尋址和立即尋址等尋址方式。上述指令的操作不影響源字節(jié)和任何別的寄存器內(nèi)容,只影響PSW的P標(biāo)志位。

注意:①工作寄存器R的下標(biāo)n和i的區(qū)別。

②立即數(shù)可以是十進(jìn)制數(shù),也可以是十六進(jìn)制數(shù),數(shù)字前都要加#號(hào)以區(qū)別直接地址。如十六進(jìn)制數(shù)首位大于等于A,即用字母表示,則字母前要加0,如#0A8H等。

(2)以寄存器Rn為目的操作數(shù)的指令有3條:這組指令的功能是把源操作數(shù)所指定的內(nèi)容送入當(dāng)前工作寄存器組R0~R7中的某個(gè)寄存器中,源操作數(shù)的內(nèi)容不發(fā)生改變,不影響PSW的內(nèi)容。源操作數(shù)有寄存器尋址、直接尋址和立即尋址等三種尋址方式。

例3-11

如果(A)=78H,(R5)=47H,(70H)=F2H,則

MOVR5,A ;(A)→R5,(R5)=78H

MOVR5,70H ;(70H)→R5,(R5)=F2H

MOVR5,#0A3H ;A3H→R5,(R5)=A3H

注意:①?8051指令系統(tǒng)中沒有“MOVRn,Rn”傳送指令。

②工作寄存器組的選擇和設(shè)置。

(3)以直接地址為目的操作數(shù)的指令有5條:這組指令的功能是把源操作數(shù)所指定的內(nèi)容送入由直接地址direct所指出的片內(nèi)存儲(chǔ)單元中,源操作數(shù)的內(nèi)容不發(fā)生改變,不影響PSW的內(nèi)容。源操作數(shù)有寄存器尋址、直接尋址、寄存器間接尋址和立即尋址等尋址方式。

注意:①“MOVdirect1,direct2”指令在譯成機(jī)器碼時(shí),源地址在前,目的地址在后,如“MOVA0H,90H”的機(jī)器碼為“8590A0”。

②低128字節(jié)可以采用直接和間接尋址方式,特殊功能寄存器的高128字節(jié)只采用直接尋址方式,而擴(kuò)展的高128字節(jié)空間只采用間接尋址方式。所以,雖然內(nèi)部RAM地址是8位,但實(shí)際的尋址空間是384字節(jié)。

(4)以間接地址為目的操作數(shù)的指令有3條:

這組指令的功能是把源操作數(shù)所指定的內(nèi)容送到由R0或R1的內(nèi)容作為地址的片內(nèi)存儲(chǔ)單元中,源操作數(shù)的內(nèi)容不發(fā)生改變,不影響PSW的內(nèi)容。源操作數(shù)有寄存器尋址、直接尋址和立即尋址等尋址方式。

例3-12

設(shè)(A)=20H,(R0)=30H,(30H)=40H,則執(zhí)行MOV@R0,A后,(A)=20H,(R0)=30H,(30H)=20H。

注意:①?Ri代表R0或R1。

②?(Ri)表示Ri中的內(nèi)容為指定的RAM單元。

(5)十六位數(shù)據(jù)傳送指令有1條:這是一條16位立即數(shù)傳送指令,其功能是把十六位常數(shù)傳送到數(shù)據(jù)指針DPTR中。DPTR由兩個(gè)8位寄存器DPH和DPL組成,該指令將高8位立即數(shù)dataH送入DPH,低8位立即數(shù)dataL送入DPL。在機(jī)器碼中,也是高位字節(jié)在前,低位字節(jié)在后。該指令不影響PSW的內(nèi)容,屬于立即尋址方式。

例如:

MOVDPTR,#1234H ;機(jī)器碼是“901234”,執(zhí)行結(jié)果是DPTR=1234H,

;DPH=12H,DPL=34H

注意:雖然MCS-51是8位機(jī),但這是一條16位數(shù)傳送指令,其功能等于“MOVDPH,#dataH”和“MOVDPL,#dataL”兩條8位數(shù)傳送指令。

2.外部數(shù)據(jù)存儲(chǔ)器數(shù)據(jù)傳送指令

在MCS-51指令系統(tǒng)中,CPU對(duì)外部RAM單元和I/O口的數(shù)據(jù)傳送只能使用寄存器間接尋址方式,與累加器A之間進(jìn)行數(shù)據(jù)傳送。由于外部RAM和I/O口是統(tǒng)一編址的,共同占用一個(gè)64K字節(jié)的空間,所以從指令本身分不出是對(duì)片外RAM的訪問還是對(duì)I/O的操作,要通過設(shè)計(jì)的硬件地址分配來決定。片外數(shù)據(jù)存儲(chǔ)器是獨(dú)立于程序存儲(chǔ)器和片內(nèi)數(shù)據(jù)存儲(chǔ)器的存儲(chǔ)空間,數(shù)據(jù)傳送使用專門的“MOVX”指令。

外部RAM數(shù)據(jù)傳送指令有4條:當(dāng)以DPTR為片外數(shù)據(jù)存儲(chǔ)器地址指針時(shí),為十六位地址,尋址范圍為64?K字節(jié)。其功能是把DPTR所指定的片外數(shù)據(jù)存儲(chǔ)器(或I/O口)內(nèi)容與累加器A之間進(jìn)行數(shù)據(jù)傳送。當(dāng)以Ri(R0或R1)為片外數(shù)據(jù)存儲(chǔ)器(或I/O口)低8位地址指針時(shí),地址由P0口送出,尋址范圍為256字節(jié),頁地址由P2口決定,共256頁,則最大尋址范圍也是64?K字節(jié)。在這種情況下,如實(shí)際尋址不到256頁,則剩余P2口管腳可做普通I/O口使用。如目的操作數(shù)是累加器A,則會(huì)影響PSW中P的內(nèi)容。

例3-13

執(zhí)行指令:

??MOV DPTR,#2000H

MOV A,#10H

MOVX @DPTR,A

上面的指令執(zhí)行后,將立即數(shù)10H送到地址為2000H的外部數(shù)據(jù)存儲(chǔ)器或I/O口中。

例3-14

執(zhí)行指令:

??MOV R0,#6FH

MOV P2,#51H

MOVX A,@R0

上面的指令執(zhí)行后,將地址為516FH的外部數(shù)據(jù)存儲(chǔ)器單元或I/O口中的數(shù)據(jù)讀到累加器A中。這時(shí)P2口提供高8位地址。

注意:①由于MCS-51沒有專門的輸入/輸出指令,只能采用這種方式與外部設(shè)備交換數(shù)據(jù),而且I/O口和外部RAM共同占用64?KB空間。

②“MOVXA,@Ri”和“MOVXA,@DPTR”這兩條指令控制線有效,從外部RAM或I/O口讀數(shù)據(jù);而“MOVX@Ri,A”和“MOVX@DPTR,A”這兩條指令控制線有效,向外部RAM或I/O口寫數(shù)據(jù)。

③?P0口低8位地址(Ri或DPL)和數(shù)據(jù)共用,P2口輸出高8位地址。

④注意“MOVX”和“MOV”指令的區(qū)別。

3.程序存儲(chǔ)器數(shù)據(jù)傳送指令

這組指令只有兩條,常用于查表操作,所以也稱為查表指令。當(dāng)數(shù)據(jù)表格存放在程序存儲(chǔ)器中時(shí)使用這組指令,完成從ROM中讀數(shù)并送累加器A的操作。這兩條指令都是單字節(jié)指令。采用了基址寄存器(DPTR或PC)加變址寄存器(A中的8位無符號(hào)數(shù))形成新的16位地址,該地址單元的內(nèi)容送到累加器A中。由于這兩條指令采用了不同的基址寄存器,因此尋址范圍有所不同。對(duì)于前一條指令,由于采用DPTR作為基址寄存器,DPTR可以任意賦值,因此這條指令的尋址范圍是整個(gè)程序存儲(chǔ)器的64?KB空間,稱為遠(yuǎn)程查表。對(duì)于后一條指令,采用PC作為基址寄存器,CPU讀取單字節(jié)指令“MOVC?A,@A+PC”后,PC的內(nèi)容先自動(dòng)加1,再將新的PC內(nèi)容與累加器A中的8位無符號(hào)數(shù)相加形成地址,取出該地址單元中的內(nèi)容送累加器A。因此,該指令只能讀出以當(dāng)前MOVC指令為起始的256個(gè)地址單元之內(nèi)的某一單元,稱其為近程查表。

4.堆棧操作指令

1)壓棧指令

該指令用于將內(nèi)部RAM低128字節(jié)單元或SFR內(nèi)容送入棧頂單元。其具體操作是:將棧指針SP加1,使它指向棧頂空單元,然后將直接地址(direct)尋址的單元內(nèi)容壓入當(dāng)前SP所指示的棧頂空單元中。本操作不影響標(biāo)志位。

2)彈棧指令

本指令用于將棧頂單元內(nèi)容取出傳送到內(nèi)部RAM低128字節(jié)單元或SFR中。其具體操作是:將棧指針SP所指示的棧頂單元中的內(nèi)容傳送到直接地址direct中,然后將棧指針SP減1,使之指向新的棧頂單元。本操作不影響標(biāo)志位。

由入棧和出棧的操作過程可以看出,堆棧中數(shù)據(jù)的壓入和彈出遵循“先進(jìn)后出”的原則。堆棧操作(PUSH為壓棧指令,POP為彈棧指令)一般用于子程序調(diào)用、中斷等,用來保護(hù)數(shù)據(jù)或保護(hù)CPU現(xiàn)場(chǎng)。

注意:①?CPU復(fù)位后SP=07H,用戶可根據(jù)計(jì)劃的棧區(qū)大小重新在內(nèi)部RAM中設(shè)定SP值。

②堆棧操作向上增長(zhǎng)。

③一般PUSH和POP指令應(yīng)成對(duì)出現(xiàn)(包括隱性存在的PUSH、POP指令,如子程序調(diào)用LCALL指令隱含壓棧2次,子程序返回指令RET隱含彈棧2次)。

5.?dāng)?shù)據(jù)交換指令

數(shù)據(jù)交換指令共有5條,實(shí)現(xiàn)累加器A和內(nèi)部RAM單元之間的字節(jié)或半字節(jié)交換。

(1)字節(jié)交換。指令完成累加器A與內(nèi)部RAM單元內(nèi)容的全字節(jié)交換。

例3-17

執(zhí)行以下指令:

?(A)=10H,(R1)=20H

XCHA,R1

執(zhí)行結(jié)果為(A)=20H,(R1)=10H。

(2)半字節(jié)交換指令實(shí)現(xiàn)累加器A與內(nèi)部RAM單元內(nèi)容的低4位進(jìn)行交換,高4位內(nèi)容不變,該操作只影響標(biāo)志位P。

例3-18

執(zhí)行以下指令:

(A)=12H,(R1)=30H,(30H)=34H

XCHDA,@R1

執(zhí)行結(jié)果為(A)=14H,(30H)=32H。

(3)累加器自身半字節(jié)交換指令實(shí)現(xiàn)累加器A內(nèi)容的高4位與低4位交換,不影響PSW的內(nèi)容。

例3-19

執(zhí)行以下指令:

(A)=12H

SWAPA

執(zhí)行結(jié)果為(A)=21H。

注意:字節(jié)和半字節(jié)的區(qū)別。3.2.2算術(shù)運(yùn)算類指令

MCS-51的算術(shù)運(yùn)算類指令共有24條,8種助記符,包括了加、減、乘、除等基本四則運(yùn)算和增量(加1)、減量(減1)運(yùn)算,執(zhí)行結(jié)果將使進(jìn)位(Cy)、輔助進(jìn)位(AC)、溢出(OV)標(biāo)志置位或復(fù)位,但加1和減1指令不影響以上標(biāo)志。

8051的算術(shù)/邏輯運(yùn)算單元(ALU)僅執(zhí)行無符號(hào)二進(jìn)制整數(shù)的算術(shù)運(yùn)算。借助溢出標(biāo)志,可對(duì)帶符號(hào)數(shù)進(jìn)行2的補(bǔ)碼運(yùn)算。借助進(jìn)位標(biāo)志,可進(jìn)行多精度加、減運(yùn)算。也可以對(duì)壓縮BCD數(shù)進(jìn)行運(yùn)算(壓縮BCD數(shù)是指在一個(gè)字節(jié)中存放2個(gè)BCD碼的數(shù))。全部算術(shù)運(yùn)算類指令都是8位數(shù)運(yùn)算。

1.不帶進(jìn)位的加法指令以上共有4條加法指令,其被加數(shù)總是累加器A,并且結(jié)果也放在A中。加法操作影響PSW中的狀態(tài)位Cy、AC、OV和P。如果位7有進(jìn)位輸出,則置位進(jìn)位標(biāo)志Cy,否則清Cy;如果位3有進(jìn)位輸出,則置位半進(jìn)位標(biāo)志AC,否則清AC;如果位6有進(jìn)位輸出而位7沒有,或者位7有進(jìn)位輸出而位6沒有,則置位溢出標(biāo)志OV,否則清OV。A中的運(yùn)算結(jié)果1的個(gè)數(shù)為奇數(shù),置位進(jìn)位標(biāo)志P,否則清P。這4條指令使累加器A可以和內(nèi)部RAM的任何一單元內(nèi)容相加,也可以和一個(gè)8位立即數(shù)相加,相加結(jié)果存放在A中。無論是哪一條加法指令,參加運(yùn)算的都是兩個(gè)8位二進(jìn)制數(shù)。對(duì)指令使用者來說,這些8位二進(jìn)制數(shù)可以當(dāng)作無符號(hào)數(shù)(0~255),也可以當(dāng)作帶符號(hào)數(shù),即補(bǔ)碼(-128~+127)。例如對(duì)于一個(gè)二進(jìn)制數(shù)11010011,用戶可以認(rèn)為它是無符號(hào)數(shù),即十進(jìn)制數(shù)211,也可以認(rèn)為它是帶符號(hào)數(shù),即十進(jìn)制數(shù)-45,但計(jì)算機(jī)在作加法運(yùn)算時(shí),總按以下規(guī)則進(jìn)行:

(2)在確定相加后進(jìn)位位Cy的值時(shí),總是把兩個(gè)操作數(shù)作為無符號(hào)數(shù)直接相加而得出進(jìn)位位Cy值。如上例中,相加后Cy=1。但若是兩個(gè)帶符號(hào)數(shù)相加,則相加后的進(jìn)位值應(yīng)該丟棄,但PSW中的Cy位仍然為1。

(3)在確定相加后溢出標(biāo)志OV的值時(shí),計(jì)算機(jī)總是把操作數(shù)當(dāng)作帶符號(hào)數(shù)來對(duì)待。在作加法運(yùn)算時(shí),一個(gè)正數(shù)和一個(gè)負(fù)數(shù)相加是不可能產(chǎn)生溢出的,只有兩個(gè)同符號(hào)數(shù)相加才有可能溢出,并可按以下方法判斷是否產(chǎn)生溢出:

●兩個(gè)正數(shù)相加(符號(hào)位都為0),若和為負(fù)數(shù)(符號(hào)位為1),則一定溢出?!駜蓚€(gè)負(fù)數(shù)相加(符號(hào)位都為1),若和為正數(shù)(符號(hào)位為0),則一定溢出。

產(chǎn)生溢出時(shí),使溢出標(biāo)志OV=l,否則OV=0。在上例中,兩個(gè)負(fù)數(shù)相加后,和仍為負(fù)數(shù),故沒有溢出,OV=0。又如,若A=01001001,執(zhí)行指令A(yù)DDA,#6BH的結(jié)果為

由于兩個(gè)正數(shù)相加為負(fù)數(shù),表示出現(xiàn)了溢出,故OV=1,同時(shí)進(jìn)位標(biāo)志Cy=0。

(4)加法指令還會(huì)影響輔助進(jìn)位標(biāo)志AC和奇偶標(biāo)志P。在上述例子中,由于第3位相加產(chǎn)生對(duì)第4位的進(jìn)位,故AC=1,又因?yàn)橄嗉雍驛中的l的數(shù)目為偶數(shù),故P=0。

注意:①二進(jìn)制、十進(jìn)制、十六進(jìn)制數(shù)和BCD碼的區(qū)別。

②進(jìn)行運(yùn)算的是有符號(hào)數(shù)還是無符號(hào)數(shù)。

③對(duì)PSW各個(gè)標(biāo)志位的影響。

2.帶進(jìn)位的加法指令

共有4條帶進(jìn)位的加法指令,其被加數(shù)總是累加器A,并且結(jié)果也放在A中。這4條指令的操作,除了指令中所規(guī)定的兩個(gè)操作數(shù)相加之外,還要加上進(jìn)位標(biāo)志Cy的值,需注意這里所指的Cy是指令開始執(zhí)行時(shí)的進(jìn)位標(biāo)志值,而不是相加過程中產(chǎn)生的進(jìn)位標(biāo)志值。只要指令執(zhí)行時(shí)Cy=0,則這4條指令的執(zhí)行結(jié)果就和普通加法指令的執(zhí)行結(jié)果一樣。帶進(jìn)位加法指令主要用于多字節(jié)二進(jìn)制數(shù)的加法運(yùn)算中。這些指令的操作影響PSW中的狀態(tài)位Cy、AC、OV和P。如果位7有進(jìn)位輸出,則置位進(jìn)位標(biāo)志Cy,否則清Cy;如果位3有進(jìn)位輸出,則置位半進(jìn)位標(biāo)志AC,否則清AC;如果位6有進(jìn)位輸出而位7沒有,或者位7有進(jìn)位輸出而位6沒有,則置位溢出標(biāo)志OV,否則清OV。A中的運(yùn)算結(jié)果1的個(gè)數(shù)為奇數(shù),置位進(jìn)位標(biāo)志P,否則清P。

例3-20

若(A)=11010011,(R1)=11101000,(Cy)=1,執(zhí)行指令“ADDCA,R1”后,(A)=10111100,Cy=1,AC=0,OV=0,P=1。

注意:帶進(jìn)位加法與不帶進(jìn)位加法的區(qū)別。

3.帶借位減法指令

帶借位減法指令有4條,與帶進(jìn)位加法指令類似,從累加器A中減去源操作數(shù)所指出的內(nèi)容及進(jìn)位位Cy的值,差值保留在累加器A中。減法指令只有一組帶借位減法指令,而沒有不帶借位的減法指令。若要進(jìn)行不帶借位的減法操作,則在減法之前要先用指令使Cy清0(CLRC),然后再相減。這些指令的操作影響PSW中的狀態(tài)位Cy、AC、OV和P。如果位7有借位,則置位進(jìn)位標(biāo)志Cy,否則清Cy;如果位3有借位,則置位半進(jìn)位標(biāo)志AC,否則清AC;如果位6有借位而位7沒有,或者位7有借位而位6沒有,則置位溢出標(biāo)志OV,否則清OV。溢出標(biāo)志OV在CPU內(nèi)部根據(jù)異或門輸出置位,OV=C7C6。A中的運(yùn)算結(jié)果1的個(gè)數(shù)為奇數(shù),置位進(jìn)位標(biāo)志P,否則清P。

對(duì)于減法操作,計(jì)算機(jī)也是對(duì)兩個(gè)操作數(shù)直接求差,并取得借位Cy的值。在判斷是否溢出時(shí),可按有符號(hào)數(shù)處理,判斷的規(guī)則為:

(1)正數(shù)減正數(shù)或負(fù)數(shù)減負(fù)數(shù)都不可能溢出,OV一定為0。

(2)若一個(gè)正數(shù)減負(fù)數(shù),差為負(fù)數(shù),則一定溢出,OV=1。

(3)若一個(gè)負(fù)數(shù)減正數(shù),差為正數(shù),也一定溢出,OV=1。

減法指令也要影響Cy、AC、OV和P標(biāo)志。若A=52H,R0=B4H,Cy=0,則執(zhí)行指令“SUBBA,R0”的結(jié)果為得A=9EH,Cy=1,AC=1,OV=1,P=1,即相減時(shí)最高位有借位,運(yùn)算結(jié)果產(chǎn)生溢出,累加器A中1的數(shù)目為奇數(shù)。

如果在進(jìn)行單字節(jié)或多字節(jié)減法前不知道進(jìn)位標(biāo)志位Cy的值,則應(yīng)在減法指令前先將Cy清0。

注意:①8051指令系統(tǒng)中沒有不帶借位的減法指令。

②運(yùn)算前Cy和運(yùn)算后Cy。

4.乘法指令參加乘法運(yùn)算的在累加器A和寄存器B中的兩個(gè)操作數(shù)是無符號(hào)數(shù),兩個(gè)8位無符號(hào)數(shù)相乘結(jié)果為16位無符號(hào)數(shù),它的高8位存放于B中,低8位存放于累加器A中。乘法指令執(zhí)行后會(huì)影響三個(gè)標(biāo)志:Cy,OV和P。執(zhí)行乘法指令后,進(jìn)位標(biāo)志一定被清除,即Cy一定為0;若相乘后有效積為8位,即B=0,則OV=0;若相乘后有效積大于0FFH,B不等于0,則OV=1。奇偶標(biāo)志仍按A中1的個(gè)數(shù)來確定。

例3-21

若A=4EH,B=5DH,執(zhí)行指令:

??MULAB

結(jié)果為A=56H,B=1CH,OV=1,即積為BA=1C56H。

注意:①參加乘法運(yùn)算的兩個(gè)8位無符號(hào)數(shù)在累加器A和寄存器B中。

②雖然指令只有一個(gè)字節(jié),但運(yùn)行周期長(zhǎng),需要4個(gè)機(jī)器周期,所以實(shí)際應(yīng)用中有些乘法運(yùn)算常采用其它方式實(shí)現(xiàn)。

5.除法指令參加除法運(yùn)算的兩個(gè)操作數(shù)也是無符號(hào)數(shù),被除數(shù)置于累加器A中,除數(shù)置于寄存器B中。相除之后,整數(shù)商存于累加器A中,余數(shù)存于寄存器B中。除法指令也影響Cy、OV和P標(biāo)志。相除之后,Cy也一定為0,溢出標(biāo)志OV只在除數(shù)B=00H、結(jié)果無法確定時(shí)置1表示,其他情況下OV都清0。奇偶標(biāo)志P仍按一般規(guī)則確定。

例3-22

若A=0BFH,B=32H,執(zhí)行指令:

??DIVAB

結(jié)果為A=03H,B=29H,OV=0,Cy=0,P=0。

注意:①除數(shù)為0時(shí)的處理。

②操作數(shù)和結(jié)果的存放位置。6.加1指令這組指令的功能是將操作數(shù)所指定的單元內(nèi)容加l,其操作不影響程序狀態(tài)字PSW。即使原單元內(nèi)容為FFH,加1后溢出為00H,也不會(huì)影響PSW標(biāo)志。這5條指令中,唯一的例外是INCA指令可以影響奇偶標(biāo)志P。前4條指令是對(duì)單字節(jié)單元內(nèi)容加1,最后l條指令是給16位的寄存器內(nèi)容加1。

注意:“INCA”和“ADDA,#01H”這兩條指令都將累加器A的內(nèi)容加1,但后者對(duì)標(biāo)志位Cy有影響。

7.減1指令

這組指令的功能是將操作數(shù)所指定的單元內(nèi)容減l,其操作不影響程序狀態(tài)字PSW。即使原單元內(nèi)容為00H,減1后溢出為FFH,也不會(huì)影響PSW標(biāo)志。這5條指令中,唯一的例外是DECA指令可以影響奇偶標(biāo)志P。

注意:MCS-51指令系統(tǒng)沒有對(duì)DPTR減1的指令。

8.十進(jìn)制調(diào)整指令

這條指令跟在ADD或ADDC指令后,將相加后存放在累加器A中的結(jié)果進(jìn)行十進(jìn)制調(diào)整,完成十進(jìn)制加法運(yùn)算功能。十進(jìn)制調(diào)整指令的功能是對(duì)BCD數(shù)加法運(yùn)算結(jié)果進(jìn)行調(diào)整。當(dāng)執(zhí)行加法運(yùn)算指令時(shí),被運(yùn)算的數(shù)屬于什么類型,CPU并不了解,運(yùn)算時(shí)一律視之為二進(jìn)制數(shù)。如果所運(yùn)算的數(shù)不是二進(jìn)制數(shù)而是BCD碼,必然得到不正確的結(jié)果,這就需要編寫程序時(shí)在加法指令之后加一個(gè)“DAA”指令,進(jìn)行加6調(diào)整。在MCS-51指令系統(tǒng)中,所有的加法運(yùn)算結(jié)果都放在累加器A中,因此這條指令是對(duì)A的內(nèi)容進(jìn)行調(diào)整。兩個(gè)壓縮BCD數(shù)執(zhí)行二進(jìn)制加法后,必須由DA指令調(diào)整后才能得到正確的BCD和。

這條指令對(duì)加法結(jié)果的調(diào)整規(guī)則是:

(1)若累加器A低4位大于9或輔助進(jìn)位標(biāo)志AC=1,則低4位加6;

(2)若累加器A高4位大于9或Cy=1,則高4位加6;

(3)若累加器A高4位等于9且低4位大于9,則高4位加6;

(4)若累加器A的最高位因調(diào)整而產(chǎn)生進(jìn)位,則將Cy置1;若不產(chǎn)生進(jìn)位,則保留Cy在調(diào)整前的狀態(tài)而并不清0。

DA指令只影響進(jìn)位標(biāo)志Cy。

本指令只能對(duì)BCD數(shù)加法結(jié)果進(jìn)行調(diào)整,不能直接使用本指令對(duì)BCD數(shù)的減法進(jìn)行調(diào)整。對(duì)BCD數(shù)減法進(jìn)行調(diào)整的方法是,將BCD數(shù)減法化為BCD數(shù)加法運(yùn)算,再進(jìn)行調(diào)整。具體來說,就是將減數(shù)化為十進(jìn)制數(shù)的補(bǔ)碼,再進(jìn)行加法運(yùn)算。BCD碼無符號(hào)數(shù)的減法運(yùn)算可按下述步驟進(jìn)行:

(1)求減數(shù)的補(bǔ)數(shù)(9AH-減數(shù));

(2)被減數(shù)與減數(shù)的補(bǔ)數(shù)相加;

(3)運(yùn)行十進(jìn)制加法調(diào)整指令。

77是正確的BCD碼結(jié)果。

對(duì)于BCD碼的加法運(yùn)算,都需要在ADD或ADDC指令之后安排一條DA指令對(duì)其運(yùn)算結(jié)果自動(dòng)進(jìn)行調(diào)整。

注意:①只有BCD碼運(yùn)算才需要調(diào)整。

②本指令不是簡(jiǎn)單地把累加器A中的十六進(jìn)制數(shù)變換成BCD碼。

3.2.3邏輯運(yùn)算類指令

MCS-51共有24條邏輯操作指令,9種助記符,完成與、或、異或、取反、移位、清除等操作。這類指令的操作數(shù)都是8位。邏輯運(yùn)算都是按位進(jìn)行的。

1.單操作數(shù)的邏輯操作指令

(1)累加器A清0指令:

這條指令的功能是將累加器A的內(nèi)容清0,即(A)=0,它不影響Cy、AC和OV標(biāo)志位,只影響P標(biāo)志位。

(2)累加器A取反指令:

這條指令的功能是對(duì)累加器A的內(nèi)容逐位取反,不影響標(biāo)志位。

(3)累加器A循環(huán)左移指令:

這條指令的功能是每執(zhí)行一次RL指令,把累加器A中的內(nèi)容向左循環(huán)移動(dòng)一位,即An移向A(n+1),最高位A7移向最低位A0,不影響標(biāo)志位。

(4)累加器A循環(huán)右移指令:

這條指令的功能是每執(zhí)行一次RR指令,把累加器A中的內(nèi)容向右循環(huán)移動(dòng)一位,即A(n+1)移向An,最低位A0移向最高位A7,不影響標(biāo)志位。

(5)累加器A帶進(jìn)位位循環(huán)左移指令:

這條指令的功能是每執(zhí)行一次RLC指令,把累加器A中的內(nèi)容連同進(jìn)位位Cy向左循環(huán)移動(dòng)一位,即An移向A(n+1),最高位A7移向進(jìn)位位Cy,Cy移向最低位A0,它會(huì)影響到標(biāo)志位。通常用“RLCA”指令實(shí)現(xiàn)將累加器A中的內(nèi)容做乘2運(yùn)算。

(6)累加器A帶進(jìn)位位循環(huán)右移指令:

這條指令的功能是每執(zhí)行一次RRC指令,把累加器A中的內(nèi)容連同進(jìn)位位Cy向右循環(huán)移動(dòng)一位,即A(n+1)移向An,最低位A0移向進(jìn)位位Cy,Cy移向最高位A7,它會(huì)影響到標(biāo)志位。通常用“RRCA”指令實(shí)現(xiàn)將累加器A中的內(nèi)容做除2運(yùn)算。2.邏輯“與”指令

邏輯“與”指令共有6條:前4條指令將累加器A的內(nèi)容和源操作數(shù)所指的內(nèi)容按位進(jìn)行邏輯“與”操作,結(jié)果存放在累加器A中。后2條指令將直接地址單元中的內(nèi)容和源操作數(shù)所指的內(nèi)容按位進(jìn)行邏輯“與”操作,結(jié)果存入直接地址單元中。這樣便于對(duì)各個(gè)特殊功能寄存器的內(nèi)容按需進(jìn)行變換,如將一個(gè)字節(jié)中的某幾位變?yōu)?,而其余位不變。如果直接地址是I/O端口,則為“讀—改—寫”操作。

注意:邏輯“與”指令按位操作,可清0。3.邏輯“或”指令

邏輯“或”指令共有6條前4條指令將累加器A的內(nèi)容和源操作數(shù)所指的內(nèi)容按位進(jìn)行邏輯“或”操作,結(jié)果存放在累加器A中。后2條指令將直接地址單元中的內(nèi)容和源操作數(shù)所指的內(nèi)容按位進(jìn)行邏輯“或”操作,結(jié)果存入直接地址單元中。這樣便于對(duì)各個(gè)特殊功能寄存器的內(nèi)容按需進(jìn)行變換,如將一個(gè)字節(jié)中的某幾位變?yōu)?,而其余位不變。如果直接地址是I/O端口,則為“讀—改—寫”操作。

注意:邏輯“或”指令按位操作,可置1。4.邏輯“異或”指令

邏輯“異或”指令共有6條:前4條指令將累加器A的內(nèi)容和源操作數(shù)所指的內(nèi)容按位進(jìn)行邏輯“異或”操作,結(jié)果存放在累加器A中。后2條指令將直接地址單元中的內(nèi)容和源操作數(shù)所指的內(nèi)容按位進(jìn)行邏輯“異或”操作,結(jié)果存入直接地址單元中。異或運(yùn)算過程為:當(dāng)兩個(gè)操作數(shù)不一致時(shí)結(jié)果為1,兩個(gè)操作數(shù)一致時(shí)結(jié)果為0。用數(shù)據(jù)0FFH異或一個(gè)寄存器的值,就能實(shí)現(xiàn)對(duì)該寄存器取反的功能。如果直接地址是I/O端口,則為“讀—改—寫”操作。

注意:邏輯“異或”指令按位操作,可求反。

5.邏輯操作指令舉例

例3-24利用左移指令對(duì)累加器A中的內(nèi)容進(jìn)行乘8操作。設(shè)(A)=01H,編程如下:

??RLA;02H→(A)

RLA;04H→(A)

RLA;08H→(A)

例3-25利用右移指令對(duì)累加器A中的內(nèi)容進(jìn)行除8操作。設(shè)(A)=08H,編程如下:

??RRA;04H→(A)

RRA;02H→(A)

RRA;01H→(A)

例3-26設(shè)P1中內(nèi)容為AAH,A中內(nèi)容為15H,執(zhí)行下列程序:

??ANLP1,#0F0H ;(P1)=A0H

ORLP1,#0FH ;(P1)=AFH

XRLP1,A ;(P1)=BAH

從例3-26可見,邏輯操作是按位進(jìn)行的?!癆NL”操作常用來屏蔽字節(jié)中的某些位,要保留的位用“1”去“與”,要清除的位用“0”去“與”。“ORL”操作常用來對(duì)字節(jié)中的某些位置“1”,要保留的位用“0”去“或”,要置1的位用“1”去“或”。“XRL”操作常用來對(duì)字節(jié)中的某些位求反,要保留的位用“0”去“異或”,要求反的位用“1”去“異或”。

例3-27把累加器A中的低4位送到外部RAM的2000H單元中,編程如下:

??MOVDPTR,#2000H ;#2000H→(DPTR)

ANL?A,#0FH ;(A)∧#0FH→(A)

MOVX@DPTR,A ;(A)→(DPTR)3.2.4控制轉(zhuǎn)移類指令

程序通常是按順序執(zhí)行的,CPU每讀取一個(gè)字節(jié)的機(jī)器碼,程序計(jì)數(shù)器PC便自動(dòng)加1,然后自動(dòng)判別是否需要讀取下一個(gè)機(jī)器碼,直至取出一條完整指令為止。每次取出一條指令并執(zhí)行完畢,就會(huì)按順序執(zhí)行下一條指令。PC內(nèi)容總是不斷地給出下一條指令的地址。如果遇到轉(zhuǎn)移指令,情況就不同了,轉(zhuǎn)移指令將直接跳轉(zhuǎn)到指令所標(biāo)明的轉(zhuǎn)移地址去取指,然后執(zhí)行該地址的指令,而不是按序執(zhí)行。這使得計(jì)算機(jī)的程序可以根據(jù)需要轉(zhuǎn)移到不同的程序段,去執(zhí)行不同的操作。計(jì)算機(jī)“智商”的高低,取決于它的轉(zhuǎn)移類指令的多少,特別是條件轉(zhuǎn)移類指令的多少,這也體現(xiàn)了轉(zhuǎn)移指令在程序中的重要性??刂妻D(zhuǎn)移類指令用于控制程序的走向,故其作用區(qū)間是程序存儲(chǔ)器空間。利用具有16位地址的長(zhǎng)調(diào)用、長(zhǎng)轉(zhuǎn)移指令可對(duì)64?KB程序存儲(chǔ)器的任一地址單元進(jìn)行訪問,也可用具有11位地址的絕對(duì)調(diào)用和絕對(duì)轉(zhuǎn)移指令,訪問2K字節(jié)的空間。另外,還有在一頁范圍的短相對(duì)轉(zhuǎn)移以及許多條件轉(zhuǎn)移指令(部分位操作指令也能實(shí)現(xiàn)控制轉(zhuǎn)移),這類指令一般不影響標(biāo)志位,下面分別給予介紹。

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

無條件轉(zhuǎn)移指令是指當(dāng)程序執(zhí)行到該指令時(shí),程序無條件地轉(zhuǎn)移到指令所提供的地址處執(zhí)行。無條件轉(zhuǎn)移指令有短轉(zhuǎn)移、長(zhǎng)轉(zhuǎn)移、相對(duì)轉(zhuǎn)移和間接轉(zhuǎn)移(散轉(zhuǎn)指令)4條。

(1)短轉(zhuǎn)移指令:

短轉(zhuǎn)移指令是一條2字節(jié)的指令,所占用空間較少。它的助記符也可以直接標(biāo)以目標(biāo)地址,例如可寫成AJMPLOOP,其中LOOP就代表目標(biāo)地址,也可寫成AJMP2300H,2300H則為所轉(zhuǎn)移地址的具體數(shù)值。它之所以稱為短轉(zhuǎn)移,是因?yàn)槠涮D(zhuǎn)的范圍只有2?KB,不如長(zhǎng)轉(zhuǎn)移指令轉(zhuǎn)移范圍為64?KB那樣大。要把短轉(zhuǎn)移指令匯編成機(jī)器碼的形式,則指令操作數(shù)須根據(jù)目標(biāo)地址的低11位填寫。執(zhí)行指令時(shí),因?yàn)槟繕?biāo)地址的高5位與指令本身當(dāng)前所在地址的高5位相同,所以可以直接取指令本身當(dāng)前地址中的高5位,只有另外的低11位取自指令本身。如果擬跳轉(zhuǎn)的目標(biāo)地址的高5位與當(dāng)前指令地址的高5位不同,則一律不能使用短轉(zhuǎn)移指令。

假如16位的目標(biāo)地址每個(gè)位分別用a0~a15表示,從短轉(zhuǎn)移指令的機(jī)器碼組成可知,其中只有11位用于表示目標(biāo)地址,即a0~a10,其余5位作為操作碼,短轉(zhuǎn)移指令的操作碼為00001,16位的組成如下所示:

a10a9a800001a7a6a5a4a3a2ala0

例3-28用一條短轉(zhuǎn)移指令,使程序能從地址2780H跳轉(zhuǎn)到2300H,寫出這條指令助記符與機(jī)器碼如下:

指令助記符AJMP2300H

指令機(jī)器碼6100

2300H寫成二進(jìn)制為 0010001100000000

求出指令機(jī)器碼為 0110000100000000

短轉(zhuǎn)移指令的機(jī)器碼只有目標(biāo)地址的低11位,跳轉(zhuǎn)不能超過當(dāng)前指令所在區(qū)域2?KB范圍。這條指令是為與MCS-48兼容而保留的指令,現(xiàn)在一般較少使用。

例3-29若在ROM中的07FDH和07FEH兩地址單元處有一條AJMP指令,試問它向高地址方向跳轉(zhuǎn)有無余地?

AJMP指令執(zhí)行過程中,要求PC值的高5位不能發(fā)生變化。但是在執(zhí)行本例的AJMP指令時(shí)PC內(nèi)容已經(jīng)等于07FFH,若向高地址跳轉(zhuǎn)就到0800H以后了,這樣高5位地址就要發(fā)生變化,這是不允許的。換言之,07FFH是第0個(gè)2?KB頁面中的最后一個(gè)字節(jié),因此從這里往高地址方向再無AJMP跳轉(zhuǎn)的余地了。

例3-29表明,籠統(tǒng)地說AJMP的跳轉(zhuǎn)范圍為2?KB是不確切的。應(yīng)當(dāng)說,AJMP跳轉(zhuǎn)的目的地址必須與AJMP后面一條指令位于同一個(gè)2?KB頁面范圍之內(nèi)。(2)長(zhǎng)轉(zhuǎn)移指令:長(zhǎng)轉(zhuǎn)移指令的目標(biāo)地址是16位的直接地址,指令由3字節(jié)組成,將指令的第二、第三字節(jié)地址碼分別裝入PC的高8位和低8位中,程序無條件轉(zhuǎn)向指定的目標(biāo)地址去執(zhí)行。該指令地址可以在64?KB范圍內(nèi)跳轉(zhuǎn),所以稱為長(zhǎng)轉(zhuǎn)移。長(zhǎng)轉(zhuǎn)移指令中的地址值一目了然,比較直觀,便于閱讀和書寫,例如LJMP2500H就表示程序要轉(zhuǎn)移到2500H單元去。它的不足之處是,指令機(jī)器碼需占用3字節(jié)空間,而且在修改程序時(shí),插入或刪除一條指令都會(huì)造成指令位置的挪動(dòng),使得所有長(zhǎng)轉(zhuǎn)移指令的目標(biāo)地址都要做相應(yīng)修改。因此編寫程序時(shí)應(yīng)盡量采用符號(hào)地址,例如LJMPNEXT,這樣盡管NEXT所代表的地址數(shù)值改變了,但只要符號(hào)本身不改變,就不需修改相應(yīng)的指令。長(zhǎng)轉(zhuǎn)移指令的執(zhí)行不影響任何標(biāo)志位。

例3-30

設(shè)標(biāo)號(hào)NEXT的地址為3010H,則執(zhí)行:

??LJMPNEXT

不管這條長(zhǎng)轉(zhuǎn)移指令存放在程序存儲(chǔ)器地址空間的什么位置,執(zhí)行這條指令后都會(huì)使程序跳轉(zhuǎn)到3010H地址處執(zhí)行。

(3)相對(duì)(短)轉(zhuǎn)移指令:相對(duì)轉(zhuǎn)移指令也是一條2字節(jié)的指令,與長(zhǎng)轉(zhuǎn)移指令相比,因?yàn)闄C(jī)器碼短,所以占用程序空間少,而且它的目標(biāo)地址是以偏移量表示的,在修改程序時(shí),只要目標(biāo)地址與當(dāng)前地址的相對(duì)位置不變,偏移量也不用改變,可以減少修改的工作量。但相對(duì)轉(zhuǎn)移指令的轉(zhuǎn)移范圍比短轉(zhuǎn)移指令還小,指令操作數(shù)的相對(duì)地址rel是一個(gè)帶符號(hào)的偏移字節(jié)數(shù)(2的補(bǔ)碼),其范圍是-128~+127(00H~7FH對(duì)應(yīng)表示0~+127,80H~FFH對(duì)應(yīng)表示-128~-1),所以跳轉(zhuǎn)范圍也不能超過1個(gè)字節(jié)帶符號(hào)補(bǔ)碼所表示的數(shù)值,即-128~+127這個(gè)范圍。如果目標(biāo)地址與當(dāng)前地址的距離超過這個(gè)范圍,顯然就不能使用這條指令。例如要轉(zhuǎn)移的目標(biāo)地址為2300H,當(dāng)前地址為2400H,目標(biāo)地址與當(dāng)前地址的距離超過規(guī)定范圍,則不能使用相對(duì)轉(zhuǎn)移指令SJMP2300H,而應(yīng)該改用LJMP2300H或者AJMP2300H。

相對(duì)轉(zhuǎn)移指令要寫成機(jī)器碼,則第一字節(jié)固定為操作碼即80H,第二字節(jié)為操作數(shù)rel,rel稱為偏移量。由于執(zhí)行本條指令時(shí),程序計(jì)數(shù)器值已指向下一條指令的地址,所以偏移量補(bǔ)碼的計(jì)算公式可簡(jiǎn)化為

rel=(目標(biāo)地址-下一條指令地址)低8位

(3-1)或采用下式計(jì)算目標(biāo)地址:

目標(biāo)地址?=PC(當(dāng)前值)?+?2?+?rel

如果程序從當(dāng)前地址往后跳,即目標(biāo)地址大于當(dāng)前地址,則rel為正。相反,若程序從當(dāng)前地址往前跳,即目標(biāo)地址小于當(dāng)前地址,則rel為負(fù)。為此規(guī)定相對(duì)轉(zhuǎn)移指令的偏移量rel必須用帶符號(hào)二進(jìn)制數(shù),并要求用補(bǔ)碼形式,以區(qū)別正負(fù)。

例3-31

設(shè)下一條指令地址為2352H,欲轉(zhuǎn)移的目標(biāo)地址

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論