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

下載本文檔

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

文檔簡介

3.1單片機(jī)的匯編語言與指令格式3.2單片機(jī)的指令尋址方式3.3單片機(jī)的指令系統(tǒng)3.4匯編語言程序設(shè)計習(xí)題33.1.1匯編語言

在計算機(jī)中,指令都是以二進(jìn)制數(shù)碼表示,并存放在程序存儲器中的。計算機(jī)按照程序規(guī)定的次序,依次從程序存儲器中取出要執(zhí)行的指令代碼,送到控制器的指令寄存器中對所取的指令進(jìn)行分析,由控制器發(fā)出完成操作所需的一系列控制電平,指揮計算機(jī)有關(guān)部件完成相應(yīng)操作。我們稱這種用二進(jìn)制代碼描述指令功能的、能被計算機(jī)直接識別的語言為機(jī)器語言(MachineLanguage)。機(jī)器語言的特點(diǎn)是:程序簡潔、速度快、占用程序空間少、能直接被計算機(jī)識別。但也有不易記憶、書寫和閱讀不便等缺點(diǎn),所以實(shí)際使用既不方便又容易出錯,很難用它進(jìn)行程序設(shè)計。3.1單片機(jī)的匯編語言與指令格式為了既能保持機(jī)器語言的特點(diǎn),又能方便編寫程序和閱讀程序,人們采用助記符號來代替機(jī)器指令代碼,助記符號與機(jī)器指令代碼一一對應(yīng),我們把這種編程語言稱為匯編語言(AssemblyLanguage)。需要說明的是,匯編語言是面向機(jī)器的程序設(shè)計語言,對于不同型號的計算機(jī),有著不同結(jié)構(gòu)的匯編語言;匯編語言中由于使用了助記符號,因此將由匯編語言編制的程序輸入計算機(jī)后,計算機(jī)不能像識別機(jī)器語言編寫的程序一樣直接識別和執(zhí)行匯編語言程序,必須通過預(yù)先放入計算機(jī)的“匯編程序”的加工和翻譯,才能把匯編語言程序變成能夠被計算機(jī)識別和處理的二進(jìn)制代碼程序。用匯編語言等非機(jī)器語言書寫好的符號程序稱為源程序,運(yùn)行時匯編程序要將源程序翻譯成機(jī)器語言程序(又稱之為目標(biāo)程序)。匯編語言程序結(jié)構(gòu)簡單,執(zhí)行速度快,程序易優(yōu)化,編譯后占用存儲空間小,是單片機(jī)應(yīng)用系統(tǒng)開發(fā)中最常用的程序設(shè)計語言。匯編語言的缺點(diǎn)是可讀性比較差,只有熟悉單片機(jī)的指令系統(tǒng),并具有一定的程序設(shè)計經(jīng)驗(yàn),才能研制出功能復(fù)雜的應(yīng)用程序。

相對而言,用高級語言(High-LevelLanguage),例如PL/M-51、FranklinC51、MBASIC51等編寫的程序,其可讀性強(qiáng),通用性好,適用于不熟悉單片機(jī)指令系統(tǒng)的的用戶。3.1.2匯編語言的指令格式

MCS-51匯編語言的指令格式為

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

其中:

[]:方括號表示該項(xiàng)是可選項(xiàng),根據(jù)指令要求確定。

標(biāo)號:用符號標(biāo)明該指令所在程序存儲器的地址,并以“:”結(jié)尾,設(shè)計者根據(jù)實(shí)際需要設(shè)置。在其他指令的操作數(shù)中可以引用該標(biāo)號作為地址。標(biāo)號是以英文字母開頭的字母、數(shù)字和某些規(guī)定的特殊符號的序列,一般不超過8個符號。

目的操作數(shù):表示操作的對象,是一個目標(biāo)地址,也是存放操作結(jié)果的地址。目的操作數(shù)與操作碼助記符之間必須用一個以上的空格分隔。

源操作數(shù):表示操作的對象或者是操作數(shù)的來源,可以是一個地址或者一個立即數(shù)。源操作數(shù)與目的操作數(shù)中間用逗號分隔。

注釋:是對指令或者程序段的解釋說明,用以提高程序的可讀性,注釋前必須加分號。注釋可用中文、英文或符號表示。需要強(qiáng)調(diào)的是,注釋僅僅是為了閱讀之用,只會出現(xiàn)在源程序中,不會出現(xiàn)在目標(biāo)程序中。3.1.3匯編語言中常用符號約定

為了便于指令的描述,對指令中常用的符號有如下約定:

(1)?Rn:表示當(dāng)前工作寄存器中的R0~R7,其中n=0~7。當(dāng)前工作寄存器組由程序狀態(tài)寄存器PSW的RS1和RS0位決定。

(2)?Ri:表示當(dāng)前工作寄存器中的R0~R1,其中i取值為0或1。

(3)?direct:表示對內(nèi)部單元直接尋址的8位地址,可以是內(nèi)部RAM區(qū)的某一單元或某一特殊功能寄存器的地址,變化范圍為00H~FFH。。

(4)?@:表示間接尋址寄存器及地址寄存器的前綴。

(5)?DPTR:表示16位數(shù)據(jù)指針。

(6)?#data:表示指令中的8位立即數(shù),其中#表示立即數(shù),data表示8位立即數(shù),取值范圍為00H~FFH。

(7)?#data16:表示指令中的16位立即數(shù),取值范圍為0000H~FFFFH。

(8)?PC:表示16位程序計數(shù)器。

(9)?addr11:表示短轉(zhuǎn)移的11位地址,用于2KB范圍內(nèi)尋址。

(10)?addr16:表示長轉(zhuǎn)移的16位地址,用于64KB范圍內(nèi)尋址。

(11)?rel:表示相對轉(zhuǎn)移的地址偏移量。

(12)?bit:表示位尋址區(qū)的直接尋址位。

(13)?(x):表示x地址單元中的內(nèi)容。

(14)?((x)):表示將x地址單元中的內(nèi)容作為地址的單元中的內(nèi)容。

(15)?←:表示操作數(shù)據(jù)的流向,將箭頭后面的內(nèi)容傳送到前面。

(16)?/:表示取反操作。指令尋找操作數(shù)地址的方式稱為尋址方式。指令中的操作數(shù)分為目的操作數(shù)和源操作數(shù),兩者參與計算機(jī)操作時都有自己的尋址方式,為了方便描述,對有目的操作數(shù)和源操作數(shù)的雙操作數(shù)指令,無特別說明情況下,其尋址方式是指源操作數(shù)的尋址方式。指令系統(tǒng)的尋址方式越多,指令功能就越強(qiáng),當(dāng)然同時指令的結(jié)構(gòu)就越復(fù)雜。

MCS-51指令系統(tǒng)共有7種尋址方式,包括立即數(shù)尋址、直接尋址、寄存器尋址、寄存器間接尋址、變址尋址、相對尋址和位尋址等。3.2單片機(jī)的指令尋址方式3.2.1立即數(shù)尋址

立即數(shù)尋址是指將操作數(shù)直接寫在指令中,不需要從其他的存儲空間中尋找和獲取。指令中立即數(shù)可以是8位或者16位,并且要在其前冠以“#”前綴,以區(qū)別于地址,主要用于賦值操作。該尋址方式只能用于源操作數(shù)。

例如:MOVA,#00H;(A)←00H

該指令執(zhí)行的操作是將立即數(shù)00H送到累加器A中,該指令就是立即數(shù)尋址。#00H中的“H”是說明該立即數(shù)是以十六進(jìn)制表示的,實(shí)際編程時也可以用其他進(jìn)制來表示。該指令的執(zhí)行過程如圖3.1所示。圖3.1立即數(shù)尋址示意圖3.2.2直接尋址

直接尋址是指把存放操作數(shù)的內(nèi)存單元的地址直接寫在指令中。在MCS-51單片機(jī)中,可以直接尋址的存儲器主要有內(nèi)部RAM區(qū)和特殊功能寄存器(SFR)區(qū)。

例如:MOVA,50H;(A)←(50H)

該指令執(zhí)行的操作是將內(nèi)部RAM中地址為50H單元的內(nèi)容傳送到累加器A中,其操作數(shù)50H就是存放數(shù)據(jù)的單元地址。所以該指令是直接尋址。若50H單元中的內(nèi)容是55H,則該指令執(zhí)行后A的內(nèi)容就是55H。該指令的執(zhí)行過程如圖3.2所示。圖3.2直接尋址示意圖3.2.3寄存器尋址

寄存器尋址是指將操作數(shù)存放于寄存器中。寄存器包括工作寄存器R0~R7、累加器A、通用寄存器B、地址寄存器DPTR和C。

例如:MOVA,R0;(A)←(R0)

該指令執(zhí)行的操作是把R0寄存器中的數(shù)據(jù)傳送到A累加器中,其操作數(shù)存放在R0中,所以尋址方式為寄存器尋址。若R0寄存器單元中的內(nèi)容是55H,則該指令執(zhí)行后A的內(nèi)容就是55H。該指令的執(zhí)行過程如圖3.3所示。圖3.3寄存器尋址示意圖特別要強(qiáng)調(diào)的是,像P0、P1、PSW等特殊寄存器沒有寄存器尋址方式,只有直接尋址方式。比如,MOVA,P0這個指令表面上是寄存器尋址,但在指令集中對應(yīng)的機(jī)器碼是不存在的,實(shí)際上執(zhí)行的是MOVA,80H(P0地址)這條指令,是直接尋址。3.2.4寄存器間接尋址

寄存器間接尋址是指將存放操作數(shù)的內(nèi)部RAM地址放在特定的寄存器中,指令中只給出該寄存器。MCS-51指令系統(tǒng)中,能用于寄存器間接尋址的寄存器有R0、R1和DPTR,稱為寄存器間接尋址寄存器,作為寄存器間接尋址時寄存器間接尋址寄存器的前面必須加上符號“@”。圖3.4寄存器間址尋址示意圖3.2.5變址尋址

變址尋址是指將基址寄存器與變址寄存器的內(nèi)容相加,結(jié)果作為操作數(shù)的地址。DPTR或PC是基址寄存器,累加器A是變址寄存器。該類尋址方式主要用于查表操作。

例如:MOVCA,@A+DPTR;(A)←((A+DPTR))

該指令執(zhí)行的操作是將累加器A的內(nèi)容和基址寄存器DPTR的內(nèi)容相加,相加結(jié)果作為操作數(shù)存放的地址(地址在程序存儲器中),再將操作數(shù)取出來送到累加器A中。若累加器A的內(nèi)容為80H,DPTR的內(nèi)容為1000H,程序存儲器單元1080H中的內(nèi)容是55H,則執(zhí)行該指令后A的內(nèi)容就是55H,執(zhí)行過程如圖3.5所示。圖3.5變址尋址示意圖3.2.6相對尋址

相對尋址是指程序計數(shù)器(PC)以當(dāng)前值(以下不做特別提示時,均指的是當(dāng)前值)為基準(zhǔn)與指令中的相對偏移量(rel)相加,形成新的有效轉(zhuǎn)移地址(下一個取指令的地址)。該類尋址方式主要用于跳轉(zhuǎn)指令。

要說明的是,該指令執(zhí)行時的程序計數(shù)器當(dāng)前值是該指令的首地址加上該指令的字節(jié)數(shù);rel是一個帶符號的8位二進(jìn)制數(shù),以補(bǔ)碼表示,能表示的范圍是-128~+127個字節(jié)單元之間,若為負(fù)數(shù)表示從當(dāng)前地址向上轉(zhuǎn)移(小于當(dāng)前地址),反之就向下轉(zhuǎn)移(大于當(dāng)前地址)。例如:SJMP08H;(PC)←(PC)+08H

該指令執(zhí)行的操作是將PC當(dāng)前的值與08H相加,結(jié)果再送回PC中,成為下一條將要執(zhí)行指令的地址。指令SJMP08H是雙字節(jié)指令,其機(jī)器碼為80H、08H,若存放在1000H處,當(dāng)執(zhí)行到該指令時,先從1000H和1001H單元取出指令,PC自動變?yōu)?002H(PC當(dāng)前值);再把PC的內(nèi)容與操作數(shù)08H相加,形成目標(biāo)地址100AH,再送回PC,使得程序跳轉(zhuǎn)到100AH單元繼續(xù)執(zhí)行,執(zhí)行過程如圖3.6所示。圖3.6相對尋址示意圖3.2.7位尋址

位尋址是指令中直接給出位地址,可以對有位地址的存儲單元進(jìn)行操作。MCS-51單片機(jī)中,操作數(shù)不僅可以按字節(jié)為單位進(jìn)行操作,也可以按位進(jìn)行操作。當(dāng)我們將某一位作為操作數(shù)時,這個操作數(shù)的地址稱為位地址。位尋址區(qū)包括在內(nèi)部RAM中的兩個特殊區(qū)域:一是內(nèi)部RAM的位尋址區(qū),字節(jié)地址范圍是20H~2FH,共16個RAM單元,對應(yīng)的位地址為00H~7FH,共128位;二是特殊功能寄存器SFR中有11個寄存器可以位尋址,可以參見第2章中有關(guān)位地址的內(nèi)容。

MCS-51單片機(jī)指令系統(tǒng)功能豐富,共有111條指令,操作碼有255個,助記符有48個??砂粗噶铋L度、執(zhí)行時間和功能等方法對指令進(jìn)行分類。

(1)按指令長度分為單字節(jié)指令(49條)、雙字節(jié)指令(46條)和三字節(jié)指令(16條)。

(2)按執(zhí)行周期分為單周期指令(64條)、雙周期指令(45條)和四周期指令(2條)。

(3)按功能分為數(shù)據(jù)傳送指令(29條)、算術(shù)運(yùn)算指令(24條)、邏輯運(yùn)算指令(24條)、位操作指令(17條)和程序控制指令(17條)。

下面按功能分類分別介紹每條指令的格式、功能、用途等。3.3單片機(jī)的指令系統(tǒng)3.3.1數(shù)據(jù)傳送類指令

數(shù)據(jù)傳送類指令是MCS-51單片機(jī)匯編語言程序設(shè)計中使用最頻繁的指令,包括內(nèi)部數(shù)據(jù)傳送、外部數(shù)據(jù)傳送、查表、數(shù)據(jù)交換、堆棧操作5種類型共29條指令,使用了8種助記符,分別為MOV、MOVX、MOVC、XCH、XCHD、SWAP、PUSH和POP。數(shù)據(jù)傳送類指令有立即尋址、直接尋址、寄存器尋址、寄存器間接尋址和變址尋址5種尋址方式。數(shù)據(jù)傳送操作是指把數(shù)據(jù)從源地址傳送到目的地址,源地址內(nèi)容不變,而目的操作數(shù)修改為源操作數(shù),或者源操作數(shù)與目的操作數(shù)互換,即源操作數(shù)變成目的操作數(shù),目的操作數(shù)變成源操作數(shù),以保存目的操作數(shù)不被丟失。

數(shù)據(jù)傳送類指令不影響標(biāo)志位(對狀態(tài)寄存器PSW操作除外),即不影響進(jìn)位標(biāo)志位Cy、半進(jìn)位標(biāo)志位AC和溢出標(biāo)志位OV,但不包括檢驗(yàn)累加器A奇偶性的標(biāo)志位P。數(shù)據(jù)傳送操作是指把數(shù)據(jù)從源地址傳送到目的地址,源地址內(nèi)容不變,而目的操作數(shù)修改為源操作數(shù),或者源操作數(shù)與目的操作數(shù)互換,即源操作數(shù)變成目的操作數(shù),目的操作數(shù)變成源操作數(shù),以保存目的操作數(shù)不被丟失。

數(shù)據(jù)傳送類指令不影響標(biāo)志位(對狀態(tài)寄存器PSW操作除外),即不影響進(jìn)位標(biāo)志位Cy、半進(jìn)位標(biāo)志位AC和溢出標(biāo)志位OV,但不包括檢驗(yàn)累加器A奇偶性的標(biāo)志位P。

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

內(nèi)部數(shù)據(jù)傳送指令共16條,主要用于內(nèi)部RAM與寄存器之間的數(shù)據(jù)傳送。指令基本格式為

MOV[目的操作數(shù)][,源操作數(shù)]

1)以累加器A為目的地址的傳送指令

此類指令共有四條,如表3.1所示。表3.1以累加器A為目的地址的傳送指令以上指令說明了在傳送類指令中,A可以接收從Rn、direct和#data傳送的數(shù)據(jù);結(jié)果影響程序狀態(tài)字寄存器中的P標(biāo)志;n=0~7,i=1~2。

例3.1

已知執(zhí)行指令前A、R0、內(nèi)部RAM30H和50H中的內(nèi)容分別是20H、30H、80H、10H,請說明每條指令的功能,并指出執(zhí)行后相應(yīng)單元內(nèi)容和奇偶標(biāo)志位P的變化。

①?MOVA,R0

②?MOVA,50H

③?MOVA,@R0

④?MOVA,#55H

解:①該指令完成了(A)←(R0);執(zhí)行后(A)=30H,P=0,其他的內(nèi)容不變。

②該指令完成了(A)←(50H);執(zhí)行后(A)=10H,P=1,其他的內(nèi)容不變。

③該指令完成了(A)←((R0));執(zhí)行后(A)=80H,P=1,其他的內(nèi)容不變。

④該指令完成了(A)←#55H;執(zhí)行后(A)=55H,P=0,其他的內(nèi)容不變。

2)以Rn為目的地址的傳送指令

該類指令共有三條,如表3.2所示。表3.2以Rn為目的地址的傳送指令以上指令說明了在傳送類指令中,Rn可以接收從A、direct和#data傳送的數(shù)據(jù)。

例3.2

設(shè)目前的工作寄存器使用的是0組,R0中的內(nèi)容是55H,R2中的內(nèi)容是50H,請判斷用下面的程序是否可以完成將R2中的內(nèi)容傳送給R0。

①?MOVR0,R2

②?MOVR0,02H

③MOVA,R2

MOVR0,A

解:①由于在指令中沒有直接Rn和Rn傳送數(shù)據(jù)的指令,故該指令不存在,所以不能完成。

②由已知得R2在RAM中地址是02H,所以該指令是將R2作為內(nèi)部RAM,用直接尋址方式完成了數(shù)據(jù)的傳送。

③指令通過A作為數(shù)據(jù)的中轉(zhuǎn),先將(A)←(R2),再將(R0)←(A),完成了數(shù)據(jù)傳送。

通過上面的例子可以看出,同樣的功能可以用多個不同的程序?qū)崿F(xiàn)。

3)以直接地址為目的地址的傳送指令

該類指令共有五條,如表3.3所示。表3.3以直接地址為目的地址的傳送指令以上指令說明了在傳送類指令中,direct可以接收從A、Rn、direct和#data傳送的數(shù)據(jù),還要注意的是,MOVdirect2,direct1指令中,匯編指令的目的操作數(shù)、源操作數(shù)與機(jī)器碼存放的次序不一致。

例3.3

設(shè)內(nèi)部RAM30H和40H中的內(nèi)容分別是18H和88H,請將40H的內(nèi)容傳給30H,分別用匯編語言和機(jī)器語言編寫該程序段,該段程序的起始地址為2000H。

解:匯編語言程序段為

2000HMOV30H,40H;(30H)

(40H)

機(jī)器語言程序段為

2000H85

2001H40

2002H30

從該程序段可以看出,匯編語言指令的目的操作數(shù)在前,源操作數(shù)在后,而機(jī)器語言剛好相反。

4)以寄存器間接地址為目的地址的傳送指令

該類指令共有三條,如表3.4所示。表3.4以寄存器間接地址為目的地址的傳送指令以上指令說明了在傳送類指令中,@Ri可以接收從A、direct和#data傳送的數(shù)據(jù),不能接收來自Rn的數(shù)據(jù)。

例3.4

已知R0、R1、內(nèi)部RAM50H和51H的內(nèi)容分別為50H、51H、30H和31H,請指出下列指令執(zhí)行后各目的操作數(shù)內(nèi)容相應(yīng)的變化。

①?MOVA,51H

MOV@R0,A

②?MOV@R1,#55H

解:①?MOVA,51H執(zhí)行后(A)=(51H)=31H;MOV@R0,A執(zhí)行后((R0))=(50H)=(A)=31H。

②?MOV@R1,#88H執(zhí)行后((R1))=(51H)=88H。

5)?16位數(shù)據(jù)傳送指令

該類指令有一條,如表3.5所示。表3.516位數(shù)據(jù)傳送指令這是唯一的一條16位立即數(shù)傳遞指令,可將一個16位的立即數(shù)送入數(shù)據(jù)指針DPTR中去,其中高8位送入DPH,低8位送入DPL。

2.外部數(shù)據(jù)傳送指令

外部數(shù)據(jù)傳送指令共四條,如表3.6所示,主要用于累加器A與外部數(shù)據(jù)存儲器或I/O端口之間的數(shù)據(jù)傳送。在此我們就可以看出內(nèi)、外部RAM的區(qū)別了,內(nèi)部RAM間可以直接進(jìn)行數(shù)據(jù)的傳遞,而外部RAM間則不行。指令基本格式為

MOVX[目的操作數(shù)][,源操作數(shù)]表3.6外部數(shù)據(jù)傳送指令

以上指令說明CPU與外部的數(shù)據(jù)傳送只能通過累加器A來實(shí)現(xiàn);累加器A與外部RAM之間傳送數(shù)據(jù)時只能用間接尋址方式,間接尋址寄存器為DPTR、R0和R1;DPTR能尋址的范圍是64KB,而R0和R1只能尋址256B以內(nèi)。以上傳送指令的結(jié)果通常影響程序狀態(tài)字寄存器的P標(biāo)志。

例3.5

把外部數(shù)據(jù)存儲器2000H單元中的數(shù)據(jù)傳送到外部數(shù)據(jù)存儲器2100H單元中。

解:MOVDPTR,#2000H

MOVXA,@DPTR;先將2000H單元的內(nèi)容傳送到

累加器A中

MOVDPTR,#2100H

MOVX@DPTR,A;再將累加器A中的內(nèi)容傳送

到2100H單元中

3.交換類指令

交換類指令共五條,主要用于累加器A與內(nèi)部數(shù)據(jù)存儲單元之間的數(shù)據(jù)傳送。與其他的數(shù)據(jù)傳送指令不同的是數(shù)據(jù)傳送是雙向的,即目的操作數(shù)和源操作數(shù)在指令執(zhí)行時互為目的地址和源地址,指令執(zhí)行后各自的操作數(shù)都修改為另一方的操作數(shù),兩個操作數(shù)都會保留而不會因數(shù)據(jù)的傳送而丟失。

1)字節(jié)交換指令

字節(jié)交換指令共三條,如表3.7所示。表3.7字節(jié)交換指令以上指令執(zhí)行后兩個操作數(shù)相互交換;A可以和內(nèi)部RAM中的任一個單元交換內(nèi)容;指令結(jié)果影響程序狀態(tài)字寄存器的P標(biāo)志。

2)半字節(jié)交換指令

半字節(jié)交換指令有一條,如表3.8所示。表3.8半字節(jié)交換指令該指令執(zhí)行后兩個操作數(shù)的低4位相互交換,高4位不變;A可以通過Ri間址和內(nèi)部RAM中的任一個單元交換內(nèi)容;指令結(jié)果影響程序狀態(tài)字寄存器的P標(biāo)志。

3)累加器A中高4位和低4位交換

累加器A中高4位和低4位交換的指令有一條,如表3.9所示。表3.9累加器A中高4位和低4位交換指令

該指令執(zhí)行后A的低4位和高4位相互交換;指令結(jié)果不影響程序狀態(tài)字寄存器的標(biāo)志位。

例3.6

設(shè)內(nèi)部數(shù)據(jù)存儲區(qū)2AH、2BH單元中連續(xù)存放有四個BCD碼:a3a2和a1a0,試編寫一程序把這四個BCD碼倒序排序,即a0a1和a2a3。

解:MOV

A,2AH;將2AH(a3a2)傳送到A(a3a2)中

SWAPA ;將A(a3a2)中的高4位與低4位交換

為A(a2a3)

XCHA,2BH;將A(a2a3)與2BH(a1a0)的內(nèi)容互換

SWAPA ;將A(a1a0)中的高4位與低4位交換

為A(a0a1)

MOV 2AH,A;累加器A(a0a1)的內(nèi)容傳送到

2AH(a0a1)單元

4.查表指令

本組指令有兩條,如表3.10所示,用于將程序存儲器ROM中的數(shù)送入A中。本組指令之所以被稱為查表指令,是因?yàn)槌S脕聿橐粋€已做好在ROM中的表格。指令基本格式為

MOVC[目的操作數(shù)][,源操作數(shù)]表3.10查表指令

以上指令結(jié)果影響程序狀態(tài)字寄存器的P標(biāo)志。

例3.7

有一個數(shù)在R0中,要求用查表的方法確定它的平方值(此數(shù)的取值范圍是0~5),試編寫一程序段完成之。

解:設(shè)將0~5的平方值依次放在程序存儲器1000H為首的存儲單元中。

MOVDPTR,#1000H;將1000H送入DPTR

MOVA,R0;將R0中的數(shù)送入A

MOVCA,@A+DPTR;取出該數(shù)的平方值

ORG1000H

TABLE:DB0,1,4,9,16,25

5.堆棧操作指令

本組指令有兩條,如表3.11所示。第一條為壓入指令,就是將direct中的內(nèi)容送入堆棧中;第二條為彈出指令,就是將堆棧中的內(nèi)容送回到direct中。表3.11堆棧操作指令堆棧是用戶自己設(shè)定的內(nèi)部RAM中的一塊專用存儲區(qū),使用時一定先設(shè)堆棧指針,堆棧指針缺省為SP=07H;堆棧遵循先進(jìn)后出的原則安排數(shù)據(jù);堆棧操作必須是字節(jié)操作,且只能直接尋址;堆棧通常用于臨時保護(hù)數(shù)據(jù)及子程序調(diào)用時保護(hù)現(xiàn)場/恢復(fù)現(xiàn)場,一般情況下,PUSH/POP指令都是成對使用的;結(jié)果不影響程序狀態(tài)字寄存器的標(biāo)志位。

例3.8

說明下面程序段的功能。

MOV SP,#50H

MOV A, #10H

MOV B, #20

PUSH ACC

POP B

解:MOVSP,#50H;(SP)←50H,即內(nèi)部RAM50H

是棧底

MOVA,#10H;(A)←10H

MOVB,#20;(B)←20(十進(jìn)制數(shù))

PUSHACC;(SP)←(SP)+1,(SP)=51H,

((SP))←(ACC)

POPB;(B)←((SP)),(SP)←(SP)-1,

(SP)=50H3.3.2算術(shù)運(yùn)算類指令

算術(shù)運(yùn)算類指令主要針對8位無符號數(shù),也可用于帶符號數(shù)運(yùn)算,包括加、減、乘、除、加1、減1運(yùn)算指令共24條;使用了8種助記符,分別為ADD、ADDC、SUBB、DA、INC、DEC、MUL和DIV。

算術(shù)運(yùn)算類指令通常會影響PSW的進(jìn)位標(biāo)志位Cy、半進(jìn)位標(biāo)志位AC和溢出標(biāo)志位OV,奇偶性標(biāo)志位P取決于累加器A的奇偶性;有立即尋址、直接尋址、寄存器尋址和寄存器間接尋址四種尋址方式。

1.加法指令

1)普通加法指令(4條)

普通加法指令即不帶進(jìn)位的加法指令,有四條,如表3.12所示。表3.12普通加法指令本組指令將A中的值與源操作數(shù)所指內(nèi)容相加,最終結(jié)果存在A中;結(jié)果均影響程序狀態(tài)字寄存器的Cy、OV、AC和P標(biāo)志。無符號數(shù)運(yùn)算時,關(guān)注的主要是Cy,若Cy=0表示運(yùn)算結(jié)果小于等于255,若Cy=1則表示產(chǎn)生了進(jìn)位;帶符號數(shù)運(yùn)算時,關(guān)注的主要是OV,若OV=0表示運(yùn)算正確,結(jié)果在-128~+127之間,若OV=1則表示運(yùn)算出錯,超出了-128~+127的范圍,要對結(jié)果進(jìn)行處理。

例3.9

分析下面的指令執(zhí)行后,狀態(tài)字寄存器的Cy、AC、OV和P位的狀態(tài)。

MOVA,#10H

ADD?A,#0F2H

解:指令執(zhí)行過程可用下式表示。表3.13帶進(jìn)位加法指令

ADDC與ADD的區(qū)別是加了進(jìn)位位Cy,將A中的值和其后面的值以及進(jìn)位位Cy中的值相加,最終結(jié)果存在A中,常用于多字節(jié)數(shù)加法運(yùn)算中。

例3.10

設(shè)X0、Y0存放在R1和R0中,X1、Y1存放在R3和R2中,試編寫計算雙字節(jié)加法R1R0+R3R2,并將結(jié)果存在R5R4中的程序。

解:單片機(jī)指令系統(tǒng)中只提供了8位的加法運(yùn)算指令,兩個16位數(shù)(雙字節(jié))相加可分為兩步進(jìn)行,第一步先對低8位相加,第二步再對高8位相加。MOV A,R0

ADD A,R2 ;求低8位的和并送入A中,進(jìn)位送Cy

MOV R4,A ;低8位的和存入R4

MOV A,R1

ADDCA,R3 ;求高8位與低8位進(jìn)位Cy的和并送入A

中,進(jìn)位送Cy

MOV R5,A ;低8位的和存入R5

2.減法指令

減法指令共有四條,如表3.14所示。

本組指令將A中的值減去源操作數(shù)所指內(nèi)容以及進(jìn)位位C中的值,最終結(jié)果存在A中。與加法指令相比較,減法指令中沒有不帶借位的減法指令,所以在做不帶借位的減法指令(在做第一次相減時)時,應(yīng)將Cy清零。表3.14減法指令

例3.11

設(shè)12H和34H分別存放在R1和R0中,試編寫計算R0減R1,并將結(jié)果存在60H中的程序。

解:MOVA,R0;被減數(shù)送A

CLRC;進(jìn)位標(biāo)志位Cy清零,為不帶借位的

減法做準(zhǔn)備

SUBBA,R1;與R1的內(nèi)容相減

MOV60H,A;結(jié)果存放在60H

3.?BCD碼調(diào)整指令

BCD碼調(diào)整指令有一條,如表3.15所示。表3.15BCD碼調(diào)整指令助記符格式機(jī)器碼(H)指令說明狀態(tài)字寄存器DAAD4BCD碼加法調(diào)整指令CyACOV在進(jìn)行BCD碼加法運(yùn)算時,跟在ADD和ADDC指令之后(不適用于減法),用于對累加器A中剛進(jìn)行的兩個BCD碼的加法結(jié)果進(jìn)行十進(jìn)制調(diào)整:

(1)當(dāng)累加器A中的低4位數(shù)出現(xiàn)了非BCD碼(大于9的二進(jìn)制數(shù):1010~1111)或低4位產(chǎn)生進(jìn)位(AC=1)時,則應(yīng)在低4位加6調(diào)整,以產(chǎn)生低4位正確的BCD碼結(jié)果;

(2)當(dāng)累加器A中的高4位數(shù)出現(xiàn)了非BCD碼(大于9的二進(jìn)制數(shù):1010~1111)或高4位產(chǎn)生進(jìn)位(Cy=1)時,則應(yīng)在高4位加6調(diào)整,以產(chǎn)生高4位正確的BCD碼結(jié)果。

例3.12

若(A)=01011000B,表示的BCD碼為58,(R3)=01100110B,表示的BCD碼為66,(Cy)=0。試編寫這兩個壓縮的BCD碼相加的程序,結(jié)果的百位送入51H、十位和個位送入50H。

解:由已知編寫程序段為

ADDA,R3;求R3與A的和,結(jié)果送入A中

DAA;由于是壓縮BCD碼加法,因此進(jìn)行BCD碼調(diào)

MOV50H,A;調(diào)整后的十位和個位送入(50H)=24H

MOVA,#00H ;A清零

ADDCA,#00H ;進(jìn)位標(biāo)志位的內(nèi)容作為百位送入A

MOV51H,A ;百位送入(50H)=01H表3.16加1減1指令本組指令是將指令中所指出的操作數(shù)內(nèi)容加1;最后一條指令是對于16位數(shù)據(jù)指針寄存器加DPTR1操作。在指令中如果操作數(shù)是I/O(P1~P3)端口,則其先從端口將數(shù)據(jù)“讀”出,加1后,再將修改了的數(shù)據(jù)寫回到端口中,一條指令相當(dāng)于進(jìn)行了“讀—修改—寫”三個操作,稱這類指令為“讀—修改—寫”指令。

5.減1指令

減1指令共有四條,如表3.17所示。表3.17減1指令本組指令是將指令中所指出的操作數(shù)內(nèi)容減1;應(yīng)注意沒有對16位數(shù)據(jù)指針寄存器DPTR減1操作的指令;在指令中如果操作數(shù)是I/O(P1~P3)端口,則屬于“讀—修改—寫”指令。

6.乘、除法指令

乘、除法指令共有二條,如表3.18所示。表3.18乘、除法指令乘法結(jié)果影響程序狀態(tài)字寄存器的Cy:積超過0FFH,置1,否則置0;Cy總是清0。除法結(jié)果也同樣影響程序狀態(tài)字寄存器的OV:除數(shù)為0,置1,否則為0;Cy總是清0。當(dāng)除數(shù)為0時結(jié)果不能確定。3.3.3邏輯運(yùn)算類指令

邏輯運(yùn)算類指令主要用于對兩個操作數(shù)按位進(jìn)行邏輯操作,結(jié)果送到A或直接尋址單元,包括與、或、異或、移位、取反、清零等共24條指令;使用了9種助記符,分別為ANL、ORL、XRL、CLR、CPL、RLA、RLCA、RRA和RRCA。

這類指令一般不影響標(biāo)志位,有立即尋址、直接尋址、寄存器尋址和寄存器間接尋址四種尋址方式。

1.邏輯運(yùn)算指令

1)邏輯與指令

邏輯與指令共有六條,如表3.19所示。表3.19邏輯與指令表3.20邏輯或指令表3.21邏輯異或指令表3.22累加器A清0和取反指令

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

循環(huán)移位指令共有四條,如表3.22所示。表3.22循環(huán)移位指令本組指令的功能是將A的內(nèi)容按指令指定的方向(左或右)和方式(帶或不帶進(jìn)位)進(jìn)行簡單的移位,每執(zhí)行一次指令移動1位。執(zhí)行帶進(jìn)位的循環(huán)移指令之前,必須給Cy置位或清0,這樣才能確定移位以后的結(jié)果。對RLC、RRC指令,在Cy=0時執(zhí)行一次RLC相當(dāng)于乘以2,執(zhí)行一次RRC相當(dāng)于除以2。

例3.16

若(A)=10001000B=88D,試用右移指令編寫將A除以4的程序段。

解:因?yàn)閳?zhí)行一次RRC相當(dāng)于除以2,因此執(zhí)行2次即可完成除4的功能。

CLRC;由于Cy要參與操作,所以將其清零,為除2做

準(zhǔn)備

RRCA;第一次帶進(jìn)位右移:(A)=01000100B=44D

CLRC;為除以2做準(zhǔn)備

RRCA;第二次帶進(jìn)位右移:(A)=00100010B=22D3.3.4位操作類指令

位操作指令的操作數(shù)是“位”,其取值只能是0或1,故又稱之為布爾變量操作指令。位操作指令的操作對象是片內(nèi)RAM的位尋址區(qū)(即20H~2FH)和特殊功能寄存器中的11個可位尋址的寄存器(如表2.8所示)。片內(nèi)RAM的20H~2FH共16個單元128位(如表2.7所示),我們?yōu)檫@128位的每個位均定義一個名稱,為00H~7FH。位操作指令主要完成的操作是以位為對象的數(shù)據(jù)傳送、邏輯運(yùn)算和控制轉(zhuǎn)移等。共17條指令;使用了11種助記符,即MOV、SETB、JB、JNB、JBC、JC、JNC、ANL、ORL、CLR和CPL;除了對進(jìn)位位C操作的指令會對進(jìn)位標(biāo)志有影響外,其他不影響標(biāo)志位。

這類指令的位地址有四種表達(dá)方式:

(1)直接(位)地址方式,如00H。

(2)點(diǎn)操作符號方式,如ACC.4,P2.3。

(3)位名稱方式,如RS0。

(4)用戶定義名方式:如用偽指令bit。

1.位傳送指令

位傳送指令有兩條,如表3.23所示。表3.23位傳送指令該位傳送指令必須與進(jìn)位位C進(jìn)行,不能在其他兩個位之間傳送。若位地址bit是I/O端口,則為“讀—修改—寫”指令。

例3.17

編寫程序,將P1.1中的狀態(tài)送到P1.0中。

解:由于位傳送指令不能在兩個位之間直接傳送,必須通過進(jìn)位位C中轉(zhuǎn),因而有:

MOV

C,

P1.1;將P1.1中的狀態(tài)送到Cy

MOV

P1.0,

C;將Cy中的狀態(tài)送到P1.0

2.位置位和位清0指令

位置位和位清0指令共有四條,如表3.24所示。表3.24位置位和位清0指令該組指令是位清0、置位指令。若位地址bit是I/O端口,則為“讀—修改—寫”指令。

例3.18

如圖3.7所示電路,P1.1端口接了一個發(fā)光二極管,編寫點(diǎn)亮或熄滅該二極管的程序段。圖3.7例3.18電路

解:由圖3.7所示可知,當(dāng)P1.1是低電平時點(diǎn)亮,高電平時熄滅,所以程序?yàn)?/p>

CLR

P1.1;(P1.1)←0,點(diǎn)亮二極管

SETB

P1.1;(P1.1)←1,熄滅二極管

3.位運(yùn)算指令

位運(yùn)算指令共有六條,如表3.25所示。表3.25位運(yùn)算指令該組指令的結(jié)果通常影響程序狀態(tài)字寄存器的Cy標(biāo)志。若位地址bit是I/O端口,則為“讀—修改—寫”指令。注意指令系統(tǒng)中沒有位異或指令,如需異或操作,可以用其他指令組合完成。

例3.19

設(shè)X、Y、Z為三個位地址,試完成(Z)=(X)(Y)運(yùn)算的程序編程。

解:異或運(yùn)算可分解為(Z)=(X)/(Y)+/(X)(Y),程序設(shè)計如下:

MOVC,X ;(Cy)←(X)

ANLC,/Y ;(Cy)←(X)/(Y)

MOVZ,C ;(Z)←(Cy)暫存(X)/(Y)的結(jié)果

MOVC,Y ;(Cy)←(Y)

ANLC,/X ;(Cy)←(X)/(Y)

ORLC,?Z ;(Cy)←(X)/(Y)+/(X)(Y)

MOVZ,C ;保存結(jié)果

4.位轉(zhuǎn)移指令

位轉(zhuǎn)移指令共有三條,如表3.26所示。

該組指令的結(jié)果不影響程序狀態(tài)字寄存器。JBC與JB指令的區(qū)別是,前者轉(zhuǎn)移后并把尋址位清0,后者只轉(zhuǎn)移而不清0尋址位。需要再次強(qiáng)調(diào)的是,PC的當(dāng)前值是該指令的首地址加上該指令的字節(jié)數(shù);rel是一個帶符號的8位二進(jìn)制數(shù),以補(bǔ)碼表示,能表示的范圍是-128(-80H)~127(7FH)個字節(jié)單元之間,若為負(fù)數(shù)表示從當(dāng)前地址向上轉(zhuǎn)移(小于當(dāng)前地址),反之就向下轉(zhuǎn)移(大于當(dāng)前地址)。表3.26位轉(zhuǎn)移指令

例3.20

設(shè)下列指令的首地址是1000H,位20的內(nèi)容為1,試簡述下列指令執(zhí)行中各有關(guān)操作數(shù)的變化情況。

(1)1000H

JB20,08H

(2)1000H

JB20,F(xiàn)DH

(3)1000H

JB20,F(xiàn)AH

解:(1)由已知得位20的內(nèi)容為1,則該指令要跳轉(zhuǎn)到(PC)+rel的地址。由于該指令是3字節(jié)指令,因此執(zhí)行該指令時,PC的值已經(jīng)是1003H,rel是08H(正值),所以有(PC)+rel=1003H+08H=100BH,即計算機(jī)下一條指令從100BH開始。

(2)由已知得位20的內(nèi)容為1,則該指令要跳轉(zhuǎn)到(PC)+rel的地址。由于該指令是3字節(jié)指令,因此執(zhí)行該指令時,PC的值已經(jīng)是1003H,rel是FDH(是-3),所以有(PC)+rel=1003H-03H=1000H,即計算機(jī)下一條指令從1000H開始。該指令執(zhí)行后實(shí)際又回到了原來的位置,所以如果位20的內(nèi)容不變,則程序?qū)⒁恢痹谶@里循環(huán)。

(3)由已知得位20的內(nèi)容為1,則該指令要跳轉(zhuǎn)到(PC)+rel的地址。由于該指令是3字節(jié)指令,因此執(zhí)行該指令時,PC的值已經(jīng)是1003H,rel是FAH(是-6),所以有(PC)+rel=1003H-06H=0FFDH,即計算機(jī)下一條指令從0FFDH開始。

5.判Cy標(biāo)志指令

判斷Cy標(biāo)志的指令有兩條,如表3.27所示。表3.27判Cy標(biāo)志指令

例3.21

將JCrel指令用于例3.12中。

解:由已知編寫程序段如下:

ADDA,R3;求R3與A的和,結(jié)果送入A中

DAA;由于是壓縮BCD碼加法,因此進(jìn)行BCD碼

調(diào)整

MOV50H,A;調(diào)整后的十位和個位送入(50H)=24H

JC PR1;若(Cy)=1,跳至PR1,百位送1;否則清0

MOV51H,#00H ;百位送入(50H)=00H

PR1:MOV51H,#01H ;百位送入(50H)=01H3.3.5控制轉(zhuǎn)移類指令

控制轉(zhuǎn)移類指令的本質(zhì)是改變程序計數(shù)器PC的內(nèi)容,從而改變程序的執(zhí)行方向??刂妻D(zhuǎn)移指令分為無條件轉(zhuǎn)移指令、條件轉(zhuǎn)移指令和調(diào)用、返回指令,指令豐富,共有17條。此類指令一般不影響PSW的狀態(tài)。

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

1)長轉(zhuǎn)移指令

長轉(zhuǎn)移指令有一條,如表3.28所示。表3.28長轉(zhuǎn)移指令該指令可以轉(zhuǎn)移到64KB程序存儲器中的任意位置;為了編程和閱讀方便,在實(shí)際使用時,地址一般用標(biāo)號表示。

例3.22

在上電復(fù)位后,程序要跳轉(zhuǎn)到用戶程序地址標(biāo)號為START的入口程序。

解:在上電復(fù)位后,單片機(jī)的第一條指令從存儲器0000H單元開始執(zhí)行,由于0003H~0023H單元對應(yīng)的是單片機(jī)各中斷源的中斷服務(wù)入口地址,一般情況下用戶的程序不允許占用,因此第一條指令一般都是跳轉(zhuǎn)指令。程序段如下

0000HLJMPSTART;(PC)←START(16位地址)

START:…

2)絕對轉(zhuǎn)移指令

絕對轉(zhuǎn)移指令有一條,如表3.29所示。表3.29絕對轉(zhuǎn)移指令該指令轉(zhuǎn)移范圍是2KB,是一條雙字節(jié)指令。其機(jī)器碼是由11位直接地址addr11~0和指令特有操作碼00001按下列分布組成的:第一個字節(jié)a10a9a800001,第二個字節(jié)a7a6a5a4a3a2a1a0。

該指令執(zhí)行后,程序轉(zhuǎn)移目的地址是由該指令的PC當(dāng)前值(該指令在程序存儲器的首地址加該指令的字節(jié)數(shù))的高5位與指令中提供的11位直接地址組成的,即

PC15PC14PC13PC12PC11a10a9a8a7a6a5a4a3a2a1a0由于11位地址的變化范圍是000H~7FFH,即2KB范圍,轉(zhuǎn)移目的地址高5位由PC當(dāng)前值固定,因此程序可轉(zhuǎn)移的范圍只能是和PC當(dāng)前值在同一2KB范圍之內(nèi)。

例3.23

指令2020HAJMP0FFH執(zhí)行后PC的內(nèi)容是什么?

解:該指令的首地址為2020H,執(zhí)行后PC的當(dāng)前值為首地址2020H加2,即2022H,然后由2022H的高5位和11位直接地址0FFH組成新的PC值,即0010000011111111B,也即程序從20FFH開始執(zhí)行。

例3.24

指令2FFFHAJMP0FFH執(zhí)行后PC的內(nèi)容是什么?

解:該指令的首地址為2FFFH,執(zhí)行后PC的當(dāng)前值為首地址2FFFH加2,即3001H,然后由3001H的高5位和11位直接地址0FFH組成新的PC值,即0011000011111111B,也即程序從30FFH開始執(zhí)行。

以上兩個例子中,指令是相同的,但由于指令的首址不同導(dǎo)致執(zhí)行的結(jié)果是不一樣的。應(yīng)掌握該指令的執(zhí)行過程。

3)相對轉(zhuǎn)移指令

相對轉(zhuǎn)移指令有一條,如表3.30所示。表3.30相對轉(zhuǎn)移指令該指令結(jié)果不影響程序狀態(tài)字寄存器,轉(zhuǎn)移范圍是以本指令的下一條指令為中心的-128~+127字節(jié)以內(nèi)。在實(shí)際應(yīng)用中,LJMP、AJMP和SJMP后面的addr16~0、addr11~0或rel常用標(biāo)號來代替,不一定寫出它們的具體地址。

例3.25

指令2FFFHSJMP23H執(zhí)行后PC的內(nèi)容是什么?

解:該指令的首地址為2FFFH,執(zhí)行后PC的當(dāng)前值為首地址2FFFH加2,即3001H,然后由3001H加23H組成新的PC值,即(PC)=(PC)+2+23H=3024H開始執(zhí)行。

無條件轉(zhuǎn)移指令A(yù)JMP、LJMP和SJMP的不同點(diǎn):

(1)構(gòu)成不同,AJMP、LJMP后跟的是絕對地址,而SJMP后跟的是相對地址;

(2)指令長度不同,AJMP、SJMP是雙字節(jié)指令,LJMP是3字節(jié)指令;

(3)跳轉(zhuǎn)的范圍不同,SJMP為-128~127B,AJMP為2KB,而LJMP是64KB,且原則上可以替代前兩條指令。

4)間接尋址的無條件轉(zhuǎn)移指令

間接尋址的無條件轉(zhuǎn)移指令有一條,如表3.31所示。表3.31間接尋址的無條件轉(zhuǎn)移指令該指令可代替眾多的判別跳轉(zhuǎn)指令,又稱為散轉(zhuǎn)指令,多用于多分支程序結(jié)構(gòu)中。該指令的功能是把累加器中8位無符號數(shù)與數(shù)據(jù)指針DPTR中的16位數(shù)相加(模216),結(jié)果作為下條指令地址送入PC;不改變累加器和數(shù)據(jù)指針內(nèi)容,也不影響標(biāo)志位。利用這條指令能實(shí)現(xiàn)程序的散轉(zhuǎn)。

例3.26

累加器A中存放待處理命令,編號為0~7,試編寫程序,完成功能:根據(jù)A內(nèi)命令編號轉(zhuǎn)向相應(yīng)的命令處理程序。

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

1)累加器A判0指令

累加器A判0指令有兩條,如表3.32所示。表3.32累加器A判0指令表3.33比較轉(zhuǎn)移指令該組指令的功能是將兩個操作數(shù)相比較,能判斷兩數(shù)是否相等或哪個數(shù)大:如果兩者相等,就順序執(zhí)行;如果不相等,就轉(zhuǎn)移,若目的操作數(shù)大于源操作數(shù),則Cy=0,否則Cy=1。

例3.28

累加器A中存放待處理數(shù)據(jù):如果為大于或等于3CH(十進(jìn)制的60),就向內(nèi)部RAM30H加1,否則就向內(nèi)部RAM31H加1。試編寫該數(shù)據(jù)處理程序段。表3.34減1非零轉(zhuǎn)移指令

3.調(diào)用和返回指令

指令系統(tǒng)中一般都有調(diào)用子程序的指令和從子程序返回主程序的指令。在程序設(shè)計中,經(jīng)常會執(zhí)行功能完全相同的一段程序,為了減少程序編寫和調(diào)試的工作量,可使這段程序作為公用,即子程序。由主程序用調(diào)用子程序指令進(jìn)入子程序,執(zhí)行子程序后,在子程序的末尾安排一條返回主程序的指令再返回主程序,完成一次子程序調(diào)用。

1)絕對調(diào)用指令

絕對調(diào)用指令有一條,如表3.35所示。表3.35絕對調(diào)用指令該指令調(diào)用范圍與AJMP指令相同:被調(diào)用子程序入口地址必須與調(diào)用指令的下一條指令(PC當(dāng)前值)的第一字節(jié)在相同的2KB存儲區(qū)之內(nèi)。執(zhí)行的過程為:將PC當(dāng)前值壓入堆棧;將指令中的11位地址送入PC的低11位,得到了調(diào)用的子程序入口地址。

例3.30

若(SP)=60H,標(biāo)號LOOP的值為0123H,子程序SUB位于0345H,試敘述下列指令執(zhí)行過程,并說明該指令能否完成對SUB子程序的調(diào)用。如果子程序SUB位于0B45H,能否完成對SUB子程序的調(diào)用?

LOOP:ACALLSUB

SUB:…

解:先求得(PC)+2=0125H;再壓入堆棧,即(SP)+1=60H+1=61H中壓入25H,(SP)+1=61H+1=62H中壓入01H;接著完成了保護(hù)斷點(diǎn),(SP)=62H。子程序SUB位于0345H,指令中只提供了SUB的低11位地址,即addr10~0=01101000101,并送給PC10~0,PC值的高5位內(nèi)容不變,即PC15~11為00000,所以這時形成的PC值為

(PC)=0000001101000101B=0345H

說明該指令已完成對SUB子程序的調(diào)用。若子程序SUB位于0B45H,則其他過程與上面相同,不同之處是:子程序SUB位于0B45H,指令中只提供了SUB的低11位地址,即addr10~0=01101000101,并送給PC10~0,PC值的高5位內(nèi)容不變,即PC15~PC11為00000,所以這時形成的PC值為

(PC)=0000001101000101B=0345H

該地址不是我們所希望的地址0B45H,故該指令不能完成對SUB子程序的調(diào)用。

從上例中我們就可以看出:使用ACALL指令時一定要使PC當(dāng)前值與子程序入口地址的高5位地址相同,即處于同一個2KB范圍內(nèi),否則將無法完成指令的調(diào)用。

2)長調(diào)用指令

長調(diào)用指令有一條,如表3.36所示。表3.36長調(diào)用指令該指令調(diào)用范圍與LJMP指令相同,可以轉(zhuǎn)移到64KB程序存儲器中的任意位置。執(zhí)行的過程為:將PC當(dāng)前值壓入堆棧;將指令中的16位地址送入PC,得到調(diào)用的子程序的入口地址。

3)返回指令

返回指令共有兩條,如表3.37所示。表3.37返回指令該組指令用于子程序最后一條指令,實(shí)現(xiàn)由子程序返回主程序的功能。不同的是,RET指令的執(zhí)行過程是:堆棧棧頂內(nèi)容(2字節(jié),調(diào)用時保存的當(dāng)前PC值)彈出給PC,實(shí)現(xiàn)返回,只能用在子程序中;RETI指令除了具有RET指令的功能外,還要對中斷優(yōu)先級狀態(tài)觸發(fā)器清零,只能用在中斷子程序中。

4)空操作

空操作指令有一條,如表3.38所示。表3.38空操作指令該指令為單字節(jié)指令,占用一個機(jī)器周期,在該周期內(nèi)CPU不作任何操作;不影響程序狀態(tài)字寄存器;經(jīng)常用作短時間的延時。程序設(shè)計是單片機(jī)應(yīng)用系統(tǒng)設(shè)計的重要組成部分,其主要目的就是為了解決某一個問題,將指令有序地組合在一起,用計算機(jī)所能接受的語言把解決問題的步驟描述出來,也就是編制計算機(jī)的程序。常用的MCS-51程序設(shè)計語言有MBASIC51、C51等高級語言和匯編語言。目前匯編語言是單片機(jī)應(yīng)用系統(tǒng)設(shè)計常用的程序設(shè)計語言之一,特別是對于初學(xué)者,掌握匯編語言及編程方法有助于對單片機(jī)硬件的學(xué)習(xí)和計算機(jī)系統(tǒng)設(shè)計。3.4匯編語言程序設(shè)計3.4.1常用偽指令

單片機(jī)匯編語言程序設(shè)計中,除了使用指令系統(tǒng)規(guī)定的指令外,還要用到一些偽指令。偽指令又稱指示性指令,具有和指令類似的形式。匯編時偽指令并不產(chǎn)生可執(zhí)行的目標(biāo)代碼,只是對匯編過程進(jìn)行某種控制或提供某些匯編信息。不同版本的匯編語言,偽指令的符號和含義可能有所不同,但基本的用法是相似的。下面對常用的偽指令作一簡單介紹。

1.定位偽指令ORG

格式:[標(biāo)號:]ORG16位地址

功能:規(guī)定程序塊或數(shù)據(jù)塊存放的起始位置是該16位地址。在一個匯編語言源程序中允許使用多條定位偽指令,規(guī)定不同程序段的起始位置,地址應(yīng)該從小到大,地址不允許重疊。

例如:ORG1000H

MOVA,#00H

表示指令MOVA,#00H存放于1000H開始的單元。

2.匯編結(jié)束偽指令END

格式:[標(biāo)號:]END

功能:匯編語言源程序結(jié)束標(biāo)志。在該指令后的指令,匯編程序都不予以處理。在整個匯編語言程序中只能有一個匯編結(jié)束偽指令,且放在程序的末尾處。

3.定義字節(jié)偽指令DB

格式:[標(biāo)號:]DB項(xiàng)或項(xiàng)表

功能:項(xiàng)或項(xiàng)表可以是一個字節(jié)數(shù)據(jù),或用逗號分開的字符串,或以引號括起來的字符串。它表示將項(xiàng)或項(xiàng)表中的數(shù)據(jù)從左到右依次存放在指定地址單元。例如:ORG1000H

TAB:DB

2BH,0A0H,′A′,′BCD′

表示TAB的地址為1000H,從該地址開始的單元依次存放數(shù)據(jù)2BH、A0H、41H(字母A的ASCII碼)、42H(字母B的ASCII碼)、43H(字母C的ASCII碼)、44H(字母D的ASCII碼),即相當(dāng)于對這些單元賦值:

(1000H)=2BH

(1001H)=A0H

(1002H)=41H

(1003H)=42H

(1004H)=43H

(1005H)=44H

4.定義字偽指令DW

格式:[標(biāo)號:]DW項(xiàng)或項(xiàng)表

功能:與DB類似,但DW定義的項(xiàng)或項(xiàng)表字為兩個字節(jié)。存放數(shù)據(jù)時高位在前,低位在后。

例如:ORG1000H

DATA:DW3000H,90H

表示從1000H單元開始的地方存放數(shù)據(jù)30H、00H、00H、90H(90H以字的形式表示為0090H),即:

(1000H)=30H

(1001H)=00H

(1002H)=00H

(1003H)=90H

5.定義空間偽指令DS

格式:[標(biāo)號:]DS表達(dá)式

功能:從指定的地址開始,保留多少個存儲單元作為備用的空間,空間大小由表達(dá)式?jīng)Q定。

例如:ORG1000H

DLY:DS32H

TAB:DB22H

表示從1000H開始的地方預(yù)留32(1000H~101FH)個存儲字節(jié)空間,22H存放在1020H單元。

6.等值偽指令EQU

格式:標(biāo)號:EQU項(xiàng)

功能:將項(xiàng)的值賦給本語句的標(biāo)號。項(xiàng)可以是常數(shù)、地址標(biāo)號或者表達(dá)式。通常該語句放在源程序的開頭部分;在同一程序中對某個標(biāo)號賦值后,其值將不能再改變。

例如:DLY:EQU3200H

TAB:EQUDLY

第一條表示DLY地址的值是3200H,第二條表示TAB地址與DLY地址的值相等。

7.位地址賦值偽指令BIT

格式:標(biāo)號:BIT位地址

功能:將位地址賦給本語句的標(biāo)號。經(jīng)賦值的標(biāo)號可以代替指令中的位,即在程序中,標(biāo)號和該位地址是等價的。

例如:DLY1:BIT31H

DLY2:BIT32H

經(jīng)過上述定義后,在編程時,可以把DLY1和DLY2當(dāng)作位地址31H和32H。3.4.2程序設(shè)計方法

要設(shè)計一個好的程序,僅知道指令系統(tǒng)是遠(yuǎn)遠(yuǎn)不夠的,還需掌握一些編程的基本方法、程序的基本結(jié)構(gòu)及設(shè)計步驟等常識,這樣才能在編程實(shí)踐中不斷地完善自己的設(shè)計能力。

1.程序設(shè)計步驟

用匯編語言編寫一個程序的過程可分為以下幾個步驟:

(1)針對所要研究的對象進(jìn)行分析,明確要解決的問題。

(2)根據(jù)實(shí)際問題的要求和指令系統(tǒng)的特點(diǎn),決定所采用的計算公式和計算方法,即算法。算法是進(jìn)行程序設(shè)計的依據(jù),它決定了程序的正確性和程序的質(zhì)量。

(3)制定程序流程圖(稱為程序框圖)。根據(jù)所選的算法,制定出運(yùn)算步驟和順序,把運(yùn)算過程畫成程序流程圖。編寫較復(fù)雜的程序時,畫出程序流程圖是十分必要的(初學(xué)者往往不重視),它可以使程序清晰,結(jié)構(gòu)合理。按照基本結(jié)構(gòu)編寫程序,也便于編程和調(diào)試。

(4)確定數(shù)據(jù)格式,分配單片機(jī)的資源。分配內(nèi)存工作區(qū)及為有關(guān)端口地址分配內(nèi)存工作區(qū)時,要根據(jù)程序區(qū)、數(shù)據(jù)區(qū)、暫存區(qū)、堆棧區(qū)等預(yù)計所占空間大小,對片內(nèi)、外存儲區(qū)進(jìn)行合理分配并確定每個區(qū)域的首地址,便于編程使用。

(5)編制匯編源程序。

(6)程序測試。利用單片機(jī)仿真器結(jié)合單片機(jī)目標(biāo)系統(tǒng),對程序進(jìn)行測試,排除程序中的錯誤,直到正確為止。

(7)程序優(yōu)化。程序優(yōu)化就是指優(yōu)化程序結(jié)構(gòu),縮短程序長度,加快運(yùn)算速度和節(jié)省數(shù)據(jù)存儲單元。在程序設(shè)計中,經(jīng)常使用循環(huán)程序和子程序的形式來縮短程序,通過改進(jìn)算法和正確使用指令來節(jié)省工作單元和減少程序執(zhí)行的時間。

2.程序的基本結(jié)構(gòu)

程序的基本結(jié)構(gòu)有順序程序結(jié)構(gòu)、分支程序結(jié)構(gòu)和循環(huán)程序結(jié)構(gòu)三種。

1)順序程序結(jié)構(gòu)

按指令的排列順序一條條地執(zhí)行,直到全部指令執(zhí)行完畢為止的程序結(jié)構(gòu)稱為順序程序結(jié)構(gòu)。順序程序結(jié)構(gòu)在編程中是最簡單、最基本的程序結(jié)構(gòu),不管多么復(fù)雜的程序,總是由若干順序程序段所組成的。在順序程序結(jié)構(gòu)中沒有判斷、沒有分支。

順序程序結(jié)構(gòu)如圖3.8所示,程序A或程序B表示計算機(jī)的某種操作,箭頭表示程序指令的方向。圖3.8順序程序結(jié)構(gòu)

2)分支程序結(jié)構(gòu)

根據(jù)程序要求改變程序執(zhí)行順序,即程序的流向有兩個或兩個以上的出口,根據(jù)指定的條件選擇程序流向的程序結(jié)構(gòu)稱為分支程序結(jié)構(gòu)。實(shí)際問題一般都是比較復(fù)雜的,單使用順序結(jié)構(gòu)程序是無法解決的,因?yàn)閷?shí)際問題總是伴隨有邏輯判斷或條件選擇,要求計算機(jī)能根據(jù)給定的條件進(jìn)行判斷,選擇不同的處理路徑。編程的關(guān)鍵是如何確定供判斷或選擇的條件以及選擇合理的分支指令。

單分支程序結(jié)構(gòu)如圖3.9所示,單分支結(jié)構(gòu)的特點(diǎn)是:一個入口,兩個出口。該結(jié)構(gòu)中有一個判斷框,根據(jù)條件C是否成立選擇執(zhí)行分支程序A或分支程序B。圖3.9單分支程序結(jié)構(gòu)

3)循環(huán)程序結(jié)構(gòu)

在一定的條件成立或不成立時,反復(fù)執(zhí)行一段程序,稱為循環(huán)程序結(jié)構(gòu)。這種結(jié)構(gòu)可大大縮短程序代碼,減少占用的程序空間,優(yōu)化程序結(jié)構(gòu),提高程序質(zhì)量。

如圖3.10所示,循環(huán)程序結(jié)構(gòu)由兩部分組成,分別為循環(huán)體A和循環(huán)條件C。循環(huán)體A即要重復(fù)執(zhí)行的程序段;循環(huán)條件C即決定是執(zhí)行循環(huán)體或者結(jié)束循環(huán)的判斷條件。循環(huán)程序結(jié)構(gòu)又分為當(dāng)型循環(huán)程序結(jié)構(gòu)和直到型循環(huán)程序結(jié)構(gòu)兩種形式,如圖3-10(a)、(b)所示。當(dāng)型循環(huán)程序結(jié)構(gòu)先判斷循環(huán)條件C,條件成立則執(zhí)行循環(huán)體A,否則退出循環(huán);直到型循環(huán)程序結(jié)構(gòu)先執(zhí)行循環(huán)體A,再判斷循環(huán)條件C,不成立則再執(zhí)行循環(huán)體A,否則退出循環(huán)。圖3.10循環(huán)程序結(jié)構(gòu)(a)當(dāng)型循環(huán)程序結(jié)構(gòu);(b)直到型循環(huán)程序結(jié)構(gòu)

3.單片機(jī)應(yīng)用系統(tǒng)程序的組成

一個完整的單片機(jī)應(yīng)用系統(tǒng)程序由主程序和其他功能子程序組成,如圖3.11所示。圖中,單片機(jī)復(fù)位后PC為0000H,也就是程序從程序存儲器的0000H開始執(zhí)行。由于MCS-51單片機(jī)程序存儲器的0003H、000BH、0013H、001BH、0023H分別是外部中斷0、定時器0、外部中斷1、定時器1、串行口的中斷入口地址,因此主程序開始的地址一般安排在0030H之后的程序存儲器中。一般在程序存儲器的0000H處放一條無條件轉(zhuǎn)移指令(AJMP、LJMP、SJMP),以便轉(zhuǎn)到主程序的開始處。由于每個中斷入口地址之間只有8個字節(jié)的空間,一般無法完成中斷服務(wù)程序的編程需要,因而在相應(yīng)的中斷入口地址處也放一條無條件轉(zhuǎn)移指令。圖3.11單片機(jī)應(yīng)用系統(tǒng)程序總體結(jié)構(gòu)

1)主程序

主程序是程序的主干,是必不可少的部分。在進(jìn)入主程序后一般來講首先要對所用的可編程的硬件資源進(jìn)行初始化,如內(nèi)部的中斷、定時器、串行口、有些I/O口(外部擴(kuò)展可編程芯片等)以及主要的RAM單元等;然后由主程序按順序調(diào)用各功能模塊(子程序),如顯示、鍵盤、采樣等。

2)子程序

子程序一般都是具有一定功能的程序模塊。它可被主程序或其他子程序調(diào)用。根據(jù)系統(tǒng)的具體要求,將一些功能模塊編制成子程序,如顯示模塊、鍵盤模塊、延時模塊、通信模塊、數(shù)據(jù)采集模塊、數(shù)據(jù)處理模塊、數(shù)據(jù)輸出模塊等。

在實(shí)際的單片機(jī)應(yīng)用系統(tǒng)軟件設(shè)計中,為了程序結(jié)構(gòu)更加清晰,易于設(shè)計、便于修改,增強(qiáng)程序可讀性,基本上都要使用子程序結(jié)構(gòu)。子程序作為一個具有獨(dú)立功能的程序段,編程時需注意以下幾點(diǎn):

(1)子程序的第一條指令必須有標(biāo)號:明確子程序入口地址。

(2)要有簡明扼要的子程序說明部分:說明該子程序的功能和所用到的資源,如寄存器、內(nèi)部RAM等。

(3)注意保護(hù)現(xiàn)場和恢復(fù)現(xiàn)場:如果在子程序中所用到的資源與其他程序發(fā)生了沖突,則需要進(jìn)行保護(hù)。

(4)有較強(qiáng)的通用性和可浮動性;盡可能避免使用具體的內(nèi)存單元和絕對轉(zhuǎn)移地址等,以方便程序修改。

(5)以返回指令RET結(jié)束子程序。

程序調(diào)試時在主程序中可逐個調(diào)用各功能模塊進(jìn)行調(diào)試,直到每一個模塊調(diào)試完成后,再進(jìn)行聯(lián)調(diào)。

3)中斷服務(wù)程序

中斷服務(wù)程序也是具有某種功能的程序模塊,通常執(zhí)行一些較為特殊的功能,如外部特殊事件(掉電、故障、通信等)的處理。它與子程序的區(qū)別是進(jìn)入方式不同:子程序的進(jìn)入方式是由主程序或其他子程序進(jìn)行調(diào)用,即在程序中何時運(yùn)行子程序是固定的;而中斷服務(wù)程序則不同,中斷服務(wù)程序的進(jìn)入是根據(jù)中斷產(chǎn)生,再由CPU根據(jù)實(shí)際的情況決定的,它是一個隨機(jī)的事件,可在程序運(yùn)行的任何時刻產(chǎn)生。編程時需注意事項(xiàng)與子程序的類似,只是要強(qiáng)調(diào)的是,中斷服務(wù)程序執(zhí)行完后,由中斷返回指令RETI返回到斷點(diǎn)處;由于中斷處理的是重要的事件,因此設(shè)計中斷服務(wù)程序時要簡短,運(yùn)行時間不宜過長;對于不使用的中斷最好將其關(guān)閉(有關(guān)的控制寄存器),從抗干擾的方面考慮,簡單的方法是可將不用的中斷入口地址寫一條跳轉(zhuǎn)到0000H的指令,在系統(tǒng)出現(xiàn)故障時,進(jìn)行軟件恢復(fù)系統(tǒng)。3.4.3匯編語言程序設(shè)計舉例

至此我們已基本具備了編寫匯編程序的知識,下面我們通過一些常用程序的分析,進(jìn)一步學(xué)習(xí)匯編程序的設(shè)計。

1.數(shù)據(jù)傳送程序設(shè)計

數(shù)據(jù)傳送程序是程序設(shè)計中常見的程序,MCS-51系列單片機(jī)存儲器結(jié)構(gòu)的特點(diǎn)之一是存在著四種物理存儲空間,即片內(nèi)RAM、片外RAM、片內(nèi)ROM和片外ROM。不同的物理存儲空間之間的數(shù)

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論