D幻燈片定稿MCS匯編語言程序設(shè)計_第1頁
D幻燈片定稿MCS匯編語言程序設(shè)計_第2頁
D幻燈片定稿MCS匯編語言程序設(shè)計_第3頁
D幻燈片定稿MCS匯編語言程序設(shè)計_第4頁
D幻燈片定稿MCS匯編語言程序設(shè)計_第5頁
已閱讀5頁,還剩81頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

會計學(xué)1D幻燈片定稿MCS匯編語言程序設(shè)計2.匯編語言

是一種符號語言,指令由助記符表示。與機器語言相比,匯編語言具有指令容易記憶、理解、識別和可讀性好的優(yōu)點,但實質(zhì)上由于匯編語言也是面向機器的語言,是機器語言程序的符號表示,所以用戶必須熟悉機器的硬件結(jié)構(gòu)和指令系統(tǒng),掌握計算機的工作過程才能熟練編程。匯編語言程序通常用于實時控制領(lǐng)域,其所能完成的操作不是一般高級語言所能實現(xiàn)的,而且源程序經(jīng)匯編生成的可執(zhí)行文件一般運行效率較高。另外,匯編語言所編寫的源程序與經(jīng)過匯編所產(chǎn)生的機器代碼程序之間有明顯的一一對應(yīng)關(guān)系,所以匯編語言編寫的程序同樣也存在通用性差,程序不能移植的缺點。第1頁/共86頁3.高級語言

高級語言是接近于人的自然語言形式的計算機編程語言的總稱,例如C語言、BASIC語言等都是高級語言。和匯編語言相比,高級語言指令簡單易學(xué),用戶容易掌握,且高級語言程序不依賴于具體的硬件結(jié)構(gòu)和指令系統(tǒng),程序可移植性好,但是高級語言編寫的源程序必須經(jīng)過編譯或解釋程序翻譯成目標(biāo)程序,機器才能執(zhí)行,而生成的目標(biāo)程序需占用較多的存儲單元,執(zhí)行時間較長,運行效率較低。由于目前有些高級語言不具有直接處理接口和中斷技術(shù)的功能,因此高級語言一般很少應(yīng)用于實時控制,但隨著語言的發(fā)展,這種情況將會有所改變。第2頁/共86頁4.1.2單片機匯編語言源程序的編輯和匯編

1.匯編語言的指令類型用匯編語言編寫的、具有特定功能的指令序列,稱為匯編語言源程序。源程序由兩種類型的匯編語言語句(即指令)構(gòu)成。語句是匯編語言的基本組成單位,按性質(zhì)不同分為兩類:指令性語句(機器指令)和指示性語句(偽指令)。(1)機器指令即指令系統(tǒng)中的全部指令,每條指令都有對應(yīng)的機器代碼,是機器真正能夠執(zhí)行的指令。(2)偽指令為匯編程序在匯編過程中提供控制或指示信息,并不直接產(chǎn)生機器代碼,屬于機器不能執(zhí)行的指令類型。2.匯編計算機不能直接識別和執(zhí)行源程序。因此源程序必須經(jīng)過匯編程序匯編產(chǎn)生機器碼目標(biāo)程序文件,程序才能執(zhí)行。這種將匯編語言源程序轉(zhuǎn)換成機器語言程序的過程稱為匯編。對于初學(xué)者來說,應(yīng)注意匯編語言源程序和匯編程序兩個術(shù)語的區(qū)別,它們的功能示例如圖4-1所示。第3頁/共86頁圖4-1匯編過程匯編語言源程序匯編程序目標(biāo)文件和源程序列表經(jīng)過匯編后第4頁/共86頁匯編語言源程序的匯編過程分為手工匯編和機器匯編。所謂手工匯編,即采用人工查指令表的方法將匯編指令翻譯成相應(yīng)機器代碼。通常源程序的人工匯編需要兩次才能完成,第一次匯編查找每條指令的機器代碼,第二次匯編完成地址偏移量的計算。由于手工匯編需要計算和查找,繁瑣而且容易出錯,而且程序修改時可能會引起指令的地址變化,轉(zhuǎn)移指令的偏移量也隨之改變,需要重新計算,所以手工匯編主要應(yīng)用于設(shè)計短小程序或調(diào)試程序的場合。所謂機器匯編,即采用匯編程序?qū)υ闯绦蜻M行自動匯編,由于單片機軟硬件資源的限制,該過程通常借助于PC系統(tǒng)機實現(xiàn),象這種借助于一種計算機而為另一種計算機產(chǎn)生目標(biāo)代碼的匯編方式又稱為交叉匯編。交叉匯編的原理類似于手工匯編,在匯編程序中通常存入了兩張表,即MCS-51單片機的指令代碼表和偽指令表。匯編程序通常通過兩次掃描完成匯編,第一次掃描查找源程序中每條指令的機器代碼,第二次掃描完成地址偏移量的計算,匯編后生成目標(biāo)文件和列表文件。這是目前應(yīng)用較廣的匯編方法。第5頁/共86頁縱上,匯編的主要功能為:(1)確定程序中每條匯編語言指令的指令機器碼。(2)確定每條指令在程序存儲器中的存放地址。(3)提供語法、編輯等方面的錯誤信息,但不能提供程序的邏輯錯誤。(4)產(chǎn)生目標(biāo)執(zhí)行文件(*.OBJ/*.HEX)和列表文件(*.LST)。第6頁/共86頁4.1.3MCS-51匯編語言的偽指令所謂“偽”指令,即不是真正的可執(zhí)行指令。如前所述,偽指令只能在對源程序進行匯編時起控制作用,例如設(shè)置程序的起始地址,定義符號,給程序分配一定的存儲空間等。常用的偽指令共有8條,下面分別介紹。1.ORG(Origin)——設(shè)置起始地址指令用來設(shè)定程序或數(shù)據(jù)存儲區(qū)的起始地址。指令格式為:ORG16位地址例如,有程序段如下,則表示程序存放的起始地址為1000H。指令地址機器碼 源程序

ORG 1000H 1000H782MAIN:MOVR0,#20H1002HE6 MOVA,@R0…若省略O(shè)RG指令后的16位地址,則匯編后目標(biāo)程序的起始地址默認(rèn)為0000H。ORG指令在一個源程序中可以多次使用以指定不同程序段的起始地址,但是指定的多個地址應(yīng)從小到大,不能使程序段之間產(chǎn)生重疊。第7頁/共86頁2.DB(DefineByte)——定義字節(jié)型常數(shù)指令指令的功能為從指定的存儲單元開始,定義或存儲一個或多個字節(jié)數(shù)據(jù)。指令格式為:[標(biāo)號:]DB字節(jié)常數(shù)表例如,ORG1000HTAB:DB0A3H,18,‘AB’匯編結(jié)果為:(1000H)=A3H(1001H)=12H(1003H)=41H(1004H)=42H3.DW(DefineWord)——定義字型常數(shù)指令指令的功能為從指定的存儲單元開始,定義或存儲一個或多個字?jǐn)?shù)據(jù)。通常用于在程序中定義地址表。指令格式為:[標(biāo)號:]DW字常數(shù)表一個字?jǐn)?shù)據(jù)占用兩個存儲單元,存放時高字節(jié)存入低位地址,低字節(jié)存入高位地址。例如, ORG1000HTAB:DW1234H,18,00A3H匯編結(jié)果:(1000H)=12H(1001H)=34H

(1002H)=00H(1003H)=12H

(1004H)=00H(1005H)=A3H第8頁/共86頁4.EQU(Equate)——等值指令指令功能是把操作數(shù)段中的地址或數(shù)據(jù)賦值給標(biāo)號。賦值后的標(biāo)號可在整個源程序中使用。指令格式如下:標(biāo)號EQU數(shù)據(jù)或匯編符號注意,與程序中一般意義的標(biāo)號不同的是,這里的標(biāo)號后不能加“:”。例如, ADDR EQU1000H;給ADDR賦值1000H DAT1 EQU0AH;給DAT1賦值0AH … MAIN: MOVDPTR,#ADDR;DPTR←1000H MOVA,DAT1;A←(0AH)上例中,ADDR被賦值以后,在程序中作為立即數(shù)使用,而DAT1賦值后被當(dāng)作直接地址使用。需要說明的是,使用EQU指令時必須先賦值后使用。第9頁/共86頁5.DS(DefineStore)——定義存儲區(qū)指令指令功能為從指定的單元地址開始,保留一定數(shù)量的存儲單元,以備使用。指令格式如下:[標(biāo)號:]DS表達式其中,表達式指定保留的內(nèi)存單元個數(shù)。例如,ORG1000HDS10TAB:DB10H…匯編結(jié)果:從1000H地址處開始,保留10個字節(jié)單元。(100AH)=10H。6.BIT——位地址符號指令指令功能為將位地址賦值給指定的符號名稱,通常用于位符號地址的定義。指令功能如下:字符名稱 BIT 位地址 例如,X1BITP1.0匯編結(jié)果為將位地址P1.0賦給變量X1,即在程序中便可使用X1代替位地址P1.0。第10頁/共86頁7.DATA——數(shù)據(jù)地址賦值指令指令功能為將數(shù)據(jù)地址或指令代碼地址賦值給所指定的標(biāo)號。通常在程序中用于定義數(shù)據(jù)地址。指令格式如下:標(biāo)號:DATA表達式例如,AA:DATA2000H匯編結(jié)果為:AA=2000H。注意,DATA與EQU的區(qū)別在于:EQU定義的標(biāo)識符在匯編時不在符號表中登記,因此必須先定義后使用,而DATA定義的標(biāo)識符匯編時在符號表中登記,所以可以先使用后定義。8.END——匯編語言源程序結(jié)束指令指令功能,表示源程序到此結(jié)束,END指令以后的指令匯編程序?qū)⒉挥杼幚?。一個程序中只能在末尾有一個END指令。例如,START:……END START第11頁/共86頁4.2匯編語言程序設(shè)計對于簡單程序的編寫,程序設(shè)計者往往能夠立即完成軟件的構(gòu)思與編寫,而對于比較復(fù)雜的程序設(shè)計問題,則需要科學(xué)合理的程序設(shè)計步驟。從軟件工程角度來說,開發(fā)一個應(yīng)用程序,一般需要經(jīng)過以下幾個步驟:1.分析問題,建立數(shù)學(xué)模型如果拿到問題,立即著手編寫程序代碼往往是很難成功的,通常需要首先分析題目的已知條件,了解系統(tǒng)的硬件配制,明確題目的要求和要實現(xiàn)的功能,然后建立數(shù)學(xué)模型。2.了解系統(tǒng)的硬件配置和性能指標(biāo),確定方案算法所謂算法就是為了解決問題而采取的方法和步驟。在分析問題后,應(yīng)根據(jù)系統(tǒng)的具體硬件配置和性能指標(biāo)等實際情況確定具體有效且計算機能夠執(zhí)行的方法和步驟。3.用流程圖表示出程序算法確定算法后,應(yīng)用簡單直觀的方法描述算法,以便為進一步編程做好準(zhǔn)備。算法的描述方法很多,其中比較常用的是流程圖法。一般流程圖的符號如圖4-2所示。4.根據(jù)流程圖編寫源程序使用匯編語言編寫源程序時,應(yīng)首先合理規(guī)劃和分配存儲器單元,確定程序和數(shù)據(jù)的存放區(qū)域,了解系統(tǒng)的I/O接口地址,最后按照流程圖寫出源程序。5.調(diào)試運行程序通常情況下,源程序編制好后必須經(jīng)過上機調(diào)試才能運行。調(diào)試程序的一個重要功能是修正語法和邏輯錯誤,直到達到題目的要求為止。第12頁/共86頁4.2.1順序程序設(shè)計

順序程序是程序設(shè)計中最基本的結(jié)構(gòu),又稱為簡單程序。特點為順序執(zhí)行每一條指令,直到最后。其執(zhí)行過程如圖4-3所示。S1S2圖4-3順序結(jié)構(gòu)第13頁/共86頁【例4-1】編寫一程序,將累加器A中的兩位壓縮BCD轉(zhuǎn)換成ASCII碼存入1000H、1001H片外存儲單元中。開始R0←AA←取A的低4位A←A+30H存入1000H單元A←取A的高4位A←R0A←A+30H存入1001H單元結(jié)束分析:由ASCII碼表可知,0~9的的ASCII碼為30H~39H,即BCD碼與ASCII碼值的差值為30H。因此只要將兩位BCD碼分別取出與30H相加即可獲得相應(yīng)的ASCII碼值,其算法流程圖如圖4-4所示。程序如下:ORG2000HMOVDPTR,#1000HMOVR0,AANLA,#00001111BORLA,#30HMOV@DPTR,AMOVA,R0SWAPAORLA,#30HINCDPTRMOVX@DPTR,AEND第14頁/共86頁【例4-2】已知如圖4-5所示,雙字節(jié)4位壓縮BCD碼數(shù)X存于片內(nèi)RAM30H、31H單元,Y存于32H、33H單元,編程求Z=X+Y,并將結(jié)果Z存入片內(nèi)RAM單元34H、35H、36H中ADDSUM:MOVA,30H ADDA,32H;低位字節(jié)相加

DAA;BCD碼修正

MOV34H,A;低位字節(jié)存入34H中

MOVA,31H ADDCA,33H;高位字節(jié)與低位進位相加

DAA MOV35H,A;高位字節(jié)之和存入35H中

MOVA,#0 ADDCA,#0DAA MOV36H,A;高位字節(jié)的進位存入36H中

END。從該例可以看出,多字節(jié)BCD碼相加時,應(yīng)從低位字節(jié)開始相加,每進行一次加法運算進行一次BCD碼調(diào)整才能得到正確結(jié)果。第15頁/共86頁4.2.2分支程序設(shè)計1.分支程序結(jié)構(gòu)的基本形式分支程序是程序設(shè)計中應(yīng)用非常廣泛的一種基本結(jié)構(gòu)。比如我們經(jīng)常遇到需要計算機進行邏輯判斷的情況,然后根據(jù)判斷的結(jié)果進行不同的處理。例如,比較兩個數(shù)的大小,并輸出判斷結(jié)果;根據(jù)輸入壓力的不同,用不同的方法計算發(fā)動機功率等這些問題都是順序結(jié)構(gòu)程序所無法實現(xiàn)的,而是屬于分支結(jié)構(gòu)程序設(shè)計的范疇。具體來說,如圖4-6所示,分支程序結(jié)構(gòu)具有以下三種形式。第16頁/共86頁條件S1S2YN條件S1條件NS2S1Sn…(a)單分支(b)雙分支(c)多分支第17頁/共86頁2.分支程序的設(shè)計方法依據(jù)分支結(jié)構(gòu)程序的執(zhí)行過程,結(jié)合MCS-51的指令系統(tǒng)可以得出,分支程序的實現(xiàn)需要通過條件轉(zhuǎn)移指令完成。因此如何設(shè)定分支條件便成為分支程序設(shè)計的關(guān)鍵。具體來說,其設(shè)計要點可歸納如下:(1)設(shè)定可供條件轉(zhuǎn)移指令測試的條件。通常,可以作為轉(zhuǎn)移指令判斷條件的有標(biāo)志位狀態(tài)(如進位位C的狀態(tài)),累加器A或片內(nèi)RAM中某位的結(jié)果狀態(tài)等。因此為了提供條件轉(zhuǎn)移指令的測試條件,應(yīng)在程序的轉(zhuǎn)移指令前設(shè)定影響判斷條件的標(biāo)志位狀態(tài),或通過邏輯運算、算術(shù)運算等指令影響標(biāo)志位。例如,若要使用JZ指令實現(xiàn)分支,則應(yīng)在該指令前執(zhí)行影響累加器A的指令。(2)根據(jù)標(biāo)志位狀態(tài)選擇正確的條件轉(zhuǎn)移指令。例如,要判斷進位位,可使用JNC或JC等指令。(3)應(yīng)在轉(zhuǎn)移的目的地址處設(shè)定標(biāo)號。第18頁/共86頁【例4-4】求8位有符號數(shù)的補碼。設(shè)8位二進制數(shù)存放在片內(nèi)RAM30H單元內(nèi)。分析:對于二進制數(shù)的補碼負(fù)數(shù)可用取反加1的方法求得,而正數(shù)不變。ORG2000HMOVA,30HJNBACC.7,NEXT;為正數(shù),不進行處理CPLA ;負(fù)數(shù)取反INCA;加1MOV30H,ANEXT:SJMPNEXT;結(jié)束可以看出,該程序通過符號位是否為0來判斷該數(shù)為正數(shù)還是負(fù)數(shù),若為正數(shù)則程序結(jié)束,若為負(fù)數(shù)則變補。顯然,這是一個單分支的例子。第19頁/共86頁【例4-5】已知壓力P和功率W之間存在如下關(guān)系:(其中M為功率修正系數(shù))當(dāng)P≤10,W=P×5+M當(dāng)P>10,W=P×5-M分析:首先判斷壓力P是否大于或等于10,然后根據(jù)判定結(jié)果計算功率W。設(shè)P存在40H單元中,M存放于41H中,結(jié)果W存放于42H中,程序如下:

ORG2000HMOVA,40H ;取壓力值

MOVR3,AMOVB,#05H ;P×5MULABMOVR1,A ;將P×5的結(jié)果暫存入RMOVA,R3;取回PCJNEA,#10,L1;P≠10,轉(zhuǎn)L1SJMPNEXT;P=10,轉(zhuǎn)NEXTL1:JCNEXT ;CY=1,P<10,轉(zhuǎn)至NEXTMOVA,R1;CY=0,P>10,W=P×5-MSUBBA,41H SJMPRESULTNEXT:MOVA,41H;取M的值

ADDA,R1;W=P×5+MRESULT:MOV42H,A;存結(jié)果

END該例是一個雙分支程序,通過比較轉(zhuǎn)移指令CJNEA,#10,L1和條件判斷指令JCNEXT實現(xiàn)程序的分支,這種編程方法在分支程序設(shè)計中應(yīng)用非常廣泛,對于初學(xué)者應(yīng)仔細分析體會。第20頁/共86頁【例4-6】求符號函數(shù)Y=F(X)+1(當(dāng)X>0時)F(X)=0(當(dāng)X=0時)

-1(當(dāng)X<0時)Y=0Y=1Y=-1保存Y結(jié)束X<0?NY開始取XYNX=0?分析:這是一個多分支程序示例。設(shè)計時可考慮將判斷變量X轉(zhuǎn)化為判斷累加器A,從而使用條件判斷指令JZ來判斷是否為零。另外,由于X是有符號數(shù),因此可使用JB或JNB指令判斷符號位來實現(xiàn)分支。其流程圖如圖4-7所示。設(shè)變量X存于片內(nèi)RAM20H單元,結(jié)果Y存于21H單元,程序如下:ORG2000HMOVA,20H ;取X JZ RESULT ;X=0,Y=0 JB ACC.7,NEG;判符號位,若為1,則X<0 MOVA,#1;X>0,Y=1SJMPRESULTNEG:MOVA,#0FFH;X<0,Y=-1,將-1的補碼送ARESULT:MOV21H,A ;保存YSJMP$第21頁/共86頁Y=0Y=1Y=-1保存Y結(jié)束X<0?NY開始取XYNX=0?第22頁/共86頁3.分支表法實現(xiàn)多向分支程序的設(shè)計上例中符號函數(shù)程序是一個多向分支程序的例子,直接采用了條件轉(zhuǎn)移指令來實現(xiàn),但在實際應(yīng)用時,通常遇到根據(jù)某變量取值不同從而轉(zhuǎn)向不同分支的題目,這時經(jīng)常采用分支表法。常用的分支表主要有三種形式:轉(zhuǎn)移指令表、分支地址表和地址偏移量表。雖然分支表的構(gòu)成各異,具體的編程方法也略有不同,但實質(zhì)上都是利用散轉(zhuǎn)指令JMP@A+DPTR來實現(xiàn)的。實現(xiàn)散轉(zhuǎn)的方法主要有兩種:(1)累加器A清零,根據(jù)DPTR的內(nèi)容決定轉(zhuǎn)移的目標(biāo)地址。(2)DPTR的值作為基址不變,根據(jù)累加器A的內(nèi)容決定轉(zhuǎn)移的目標(biāo)地址。下面通過一個具體的例題,說明使用分支表實現(xiàn)多向分支程序設(shè)計的方法。第23頁/共86頁【例4-7】根據(jù)R2的內(nèi)容,轉(zhuǎn)向相應(yīng)的分支程序。即:R2=0,轉(zhuǎn)向PROG0R2=1,轉(zhuǎn)向PROG1…R2=n,轉(zhuǎn)向PROGn(1)使用轉(zhuǎn)移指令表。所謂轉(zhuǎn)移指令表即由轉(zhuǎn)移指令組成的分支表,如圖4-8所示。JMPTAB:AJMPPROG0JMPTAB:LJMPPROG0AJMPPROG1 LJMPPROG1…

…AJMPPROGn LJMPPROGn

(a)(b)圖4-8轉(zhuǎn)移指令表第24頁/共86頁設(shè)轉(zhuǎn)移指令表的標(biāo)號為JMPTAB,分支數(shù)為5,解題思路分析如圖4-9所示。DPTR←JMPTABA+DPTR←JMPTAB+R2×3JMP@A+DPTRLJMPPROG0LJMPPROGnLJMPPROG1第25頁/共86頁MOVDPTR,#JMPTAB;將JMPTAB→DPTRMOVA,R2MOVB,#03MULAB;R2×3→BAPUSHA;暫存乘積的低位字節(jié)AMOVA,BADDA,DPH;將乘積的高位字節(jié)B+DPH→DPHMOVDPH,A;POPA;將暫存的A內(nèi)容恢復(fù)

JMP@A+DPTR;散轉(zhuǎn)JMPTAB:AJMPPROG0;轉(zhuǎn)移指令表AJMPPROG1…

AJMPPROG5…PROG0:…PROG1:………PROG5:…采用第二種散轉(zhuǎn)程序設(shè)計方法,即DPTR內(nèi)容固定,根據(jù)A的值轉(zhuǎn)向不同的分支程序。則應(yīng)首先將JMPTAB→DPTR,使DPTR的內(nèi)容固定,將R2×M→A(當(dāng)使用短轉(zhuǎn)移指令表時M的值為2,當(dāng)使用長轉(zhuǎn)移指令表時M的值為3),然后使用JMP@A+DPTR指令實現(xiàn)分支。具體程序如下:第26頁/共86頁說明,因為轉(zhuǎn)移指令表由LJMP長跳轉(zhuǎn)指令構(gòu)成,因此M取值為3,其乘積的高位字節(jié)應(yīng)加在DPH上。若轉(zhuǎn)移指令表由2字節(jié)指令A(yù)JMP構(gòu)成,M取值應(yīng)為2,且各分支程序的入口地址PROG0、PROG1…必須與轉(zhuǎn)移指令表處于同一個2KB的存儲地址空間之內(nèi),而LJMP指令表則沒有這個限制。使用AJMP轉(zhuǎn)移指令表的程序如下:MOVDPTR,#JMPTAB;將JMPTAB→DPTRCLRCMOVA,R2RLCA;R2×2→AJNCNOADD;判斷是否有進位INCDPH;若有進位,將進位加到高字節(jié)DPHNOADD:JMP@A+DPTR;散轉(zhuǎn)JMPTAB:AJMPPROG0;轉(zhuǎn)移指令表AJMPPROG1…

AJMPPROG5…PROG0:…PROG1:……PROG5:…第27頁/共86頁(2)使用分支地址表。所謂分支地址表是指由各個分支程序的入口地址組成的線性表,每個入口地址占兩個連續(xù)字節(jié)單元。設(shè)PROG0…PROGn為分支程序入口地址,分支地址表如圖4-10所示。BRANCHTAB:DWPROG0DWPROG1

…DWPROGn圖4-10分支地址表DPTR←BRANCHTABA←R2×2JMP@A+DPTR分支程序PROG0分支程序PROGn分支程序PROG1DPTR←應(yīng)用MOVCA,@A+DPTR取分支地址A←0圖4-11分支地址表的使用設(shè)分支地址表的標(biāo)號為BRANCHTAB,分支數(shù)為n,使用分支地址表實現(xiàn)多向分支的解題思路分析如圖4-11所示。第28頁/共86頁DPTR←BRANCHTABA←R2×2JMP@A+DPTR

分支程序PROG0

分支程序PROGn分支程序PROG1DPTR←應(yīng)用MOVCA,@A+DPTR取分支地址A←0圖4-11分支地址表的使用第29頁/共86頁根據(jù)以上解題思路,例4-7程序編寫如下:ORG1000HMAIN:MOVDPTR,#BRANCHTAB;取分支表入口地址

MOVA,R2CLRC ;A←R2×2RLCAJNCNOADDINCDPH;進位加到DPH中NOADD:MOVR3,A;R3←R2×2 MOVCA,@A+DPTR;A←分支地址的高位字節(jié)

XCHA,R3;R3←分支地址的高位字節(jié),A←R2×2 INCA;指向下一個存儲單元

MOVCA,@A+DPTR;取分支地址的低位字節(jié)

MOVDPL,A ;

MOVDPH,R3;

CLRAJMP@A+DPTR;分支地址→PC,轉(zhuǎn)移BRANCHTAB:DWPROG0 ;分支地址表

DWPROG1

… PROG0:…

;分支程序0…PROG5:…

;分支程序5第30頁/共86頁(3)使用地址偏移量表。所謂地址偏移量表,是指由各分支程序段的入口地址與地址偏移量表的標(biāo)號差(即地址偏移量)形成的線性表。其中地址偏移量表中每項占一個字節(jié),如圖4-12所示。TAB:DBPROG0-TAB;PROG0…PROGn為分支程序入口地址

DBPROG1-TAB

…DBPROGn-TAB圖4-12地址偏移量表第31頁/共86頁DPTR←TABA←R2JMP@A+DPTR

分支程序PROG0

分支程序PROGn分支程序PROG1應(yīng)用MOVCA,@A+DPTR取分支地址偏移量圖4-13地址偏移量表的使用第32頁/共86頁根據(jù)以上解題思路,例4-7程序編寫如下:ORG1000HMOVDPTR,#TAB;取偏移量表首地址MOVA,R2MOVCA,@A+DPTR;將查表所得PROGi-TABAJMP@A+DPTR;由A+DPTR=PROGi-TAB+TAB=PROGi獲得分支程序地址實現(xiàn)跳TAB:DBPROG0-TAB;地址偏移量表DBPROG1-TAB

…DBPROGn-TABPROG0:……PROGn:…使用地址偏移量表實現(xiàn)多向分支時,應(yīng)注意要使地址偏移量表與各分支程序的長度和在同一頁(256字節(jié))范圍內(nèi),因此該方法適用于分支較少的情況。第33頁/共86頁4.2.3循環(huán)程序設(shè)計

在程序設(shè)計中,常常會涉及到重復(fù)執(zhí)行的程序段,這可以通過循環(huán)結(jié)構(gòu)來實現(xiàn),循環(huán)結(jié)構(gòu)可使程序更加緊湊。1.循環(huán)結(jié)構(gòu)程序的構(gòu)成與高級語言中循環(huán)程序的構(gòu)成相似,匯編語言的循環(huán)程序結(jié)構(gòu)主要包括以下四個部分:(1)循環(huán)初始化部分。所謂初始化即設(shè)置循環(huán)開始時的狀態(tài),如清結(jié)果單元、設(shè)置地址指針、設(shè)定寄存器初值、循環(huán)次數(shù)等。(2)循環(huán)體部分。循環(huán)體是循環(huán)結(jié)構(gòu)的主體,為需要重復(fù)執(zhí)行的程序段。(3)循環(huán)控制部分。這一部分主要完成循環(huán)條件的設(shè)定,循環(huán)控制變量的修改以及檢測循環(huán)條件是否仍然滿足,若條件成立則繼續(xù)循環(huán),否則結(jié)束循環(huán)。(4)結(jié)束部分。該部分主要完成循環(huán)結(jié)束后的結(jié)果處理工作,例如結(jié)果的保存、計算等。其執(zhí)行過程如圖4-12所示。第34頁/共86頁循環(huán)初始化執(zhí)行循環(huán)體循環(huán)條件是否成立?N開始循環(huán)結(jié)束,結(jié)果處理Y結(jié)束修改循環(huán)變量循環(huán)初始化執(zhí)行循環(huán)體循環(huán)條件是否成立?N開始循環(huán)結(jié)束,結(jié)果處理Y結(jié)束修改循環(huán)變量體第35頁/共86頁2.簡單循環(huán)程序

所謂簡單循環(huán)即一重循環(huán),也就是循環(huán)程序中只包含一個循環(huán),不嵌套其它循環(huán)的循環(huán)程序。另外,設(shè)定循環(huán)執(zhí)行的條件非常重要,否則可能形成死循環(huán)。編寫匯編語言程序時,通常采用兩種控制循環(huán)的方法。一種是使用計數(shù)的方法實現(xiàn)循環(huán),即將循環(huán)次數(shù)作為循環(huán)計數(shù)器的初值,當(dāng)計數(shù)器的值加滿(稱為正計數(shù))或減為0(稱為倒計數(shù))時結(jié)束循環(huán),否則繼續(xù)循環(huán),該方法適用于循環(huán)次數(shù)已知的情況。另一種為通過設(shè)定特定條件控制循環(huán),若設(shè)定條件滿足則執(zhí)行循環(huán),否則結(jié)束循環(huán),例如設(shè)定特定的循環(huán)結(jié)束標(biāo)志等,該方法適用于循環(huán)次數(shù)未知的情況。第36頁/共86頁【例4-8】數(shù)據(jù)塊求和。設(shè)內(nèi)部RAM中有一連續(xù)單字節(jié)數(shù)據(jù)塊,首地址為BLOCK單元,數(shù)據(jù)塊長度存于LEN單元,若數(shù)據(jù)累加和也為單字節(jié)數(shù)據(jù),并存于RESULT單元,編程求數(shù)據(jù)塊之和。分析:累加和的求解應(yīng)使用循環(huán),且數(shù)據(jù)長度已知,所以循環(huán)次數(shù)已知,因此可考慮使用指令DJNZ來控制循環(huán)條件,其算法流程圖如圖4-15所示。A←0,R0←BLOCK,R1←LEN累加求和R1≠0?N開始RESULT←和Y結(jié)束R0+1,R1-1第37頁/共86頁程序如下:ORG1000HLEN:DATA20HRESULT:DATA21HBLOCK:DATA22HMOVA,#0MOVR0,#BLOCKMOVR1,#LENLOOP:ADDA,@R0INCR0DJNZR1,LOOPMOVRESULT,AHERE:SJMPHERE可以看出,這是一個循環(huán)次數(shù)已知的例題。第38頁/共86頁【例4-9】求均值。已知一控制系統(tǒng),從P1口讀入采樣值,每周期采樣16次,試編程求其每周期的采樣均值。分析:要求平均值,應(yīng)先求得16次采樣的數(shù)據(jù)和,然后除以16即可。由于16=24,因此可使用指令右移指令RRC完成除法運算。設(shè)累加和存于寄存器R0R1中,其具體程序如下:ORG1000HMOVR0,#0;清零,保存和的高位字節(jié)MOVR1,#0;清零,保存和的低位字節(jié)MOVR3,#16;R3用作計數(shù)器L1:MOVP1,#0FFH;置P1為輸入口MOVA,P1;讀入采樣值A(chǔ)DDA,R1;累加JNCL2;若無進位,轉(zhuǎn)L2INCR0;進位加到高位字節(jié)L2:MOVR1,ADJNZR3,L1;16次采樣值是否累加完?

MOVR4,#4;R4←右移次數(shù)4L3:MOVA,R0RRCA;高位字節(jié)右移1位

MOVR0,AMOVA,R1RRCA;低位字節(jié)右移1位

MOVR1,ADJNZR4,L3;循環(huán)4次完成除以16HERE:SJMPHERE第39頁/共86頁【例4-10】求最小值。設(shè)內(nèi)部RAM中有一無符號數(shù)數(shù)據(jù)塊,其首地址為BLOCK,長度存于LEN單元,試求出數(shù)據(jù)塊中的最小值,存入MIN單元。分析:求最小值時,通常采用比較交換的方法。即首先取第一個數(shù)作為基準(zhǔn),然后將基準(zhǔn)數(shù)與第二個數(shù)進行比較,若基準(zhǔn)數(shù)大于第二個數(shù),則兩數(shù)進行交換;若基準(zhǔn)數(shù)小于第二個數(shù)則不進行交換,總之保證基準(zhǔn)數(shù)單元中的值為最小值,再取下一個數(shù)與基準(zhǔn)數(shù)進行比較,一直到所有數(shù)據(jù)比較完為止,則基準(zhǔn)數(shù)單元中的數(shù)則為最小值。依此類推,求最大值也可采用類似方法。其算法流程圖如圖4-16所示。第40頁/共86頁A←0,R1←BLOCK,R2←LEN清CYA←A-(R1)R2≠0?N開始MIN←AY結(jié)束R1+1,R2-1CY=1?

A←(R1)NA←A+(R1)Y第41頁/共86頁具體程序編寫如下:ORG1000HMIN:DATA20HLEN:DATA21HBLOCK:DATA22HCLRAMOVR2,LENMOVR1,#BLOCK;取數(shù)據(jù)塊首地址LOOP:CLRC;清CY準(zhǔn)備做減法SUBBA,@R1JCNEXT;A<(R1),轉(zhuǎn)NEXTMOVA,@R1;A>(R1),則A←(R1)SJMPNEXT1NEXT:ADDA,@R1;A<(R1),恢復(fù)ANEXT1:INCR1DJNZR2,LOOPMOVMIN,A;存最小值HERE:SJMPHERE第42頁/共86頁【例4-11】設(shè)片內(nèi)RAM中有一無符號數(shù)數(shù)據(jù)塊,其首地址為BLOCK,長度未知,但數(shù)據(jù)結(jié)束標(biāo)志存于LEN單元,求數(shù)據(jù)塊的最小值并存于MIN單元中。

ORG1000HMIN:DATA20HLEN:DATA21HBLOCK:DATA22HMAIN:MOV R1,#BLOCK ;數(shù)表首地址

MOVB,@R1 ;取第一個數(shù)作為基準(zhǔn)NEXT:INC R1 ;修改指針

MOVA,@R1CJNEA,LEN,NEXT1;是否為數(shù)表結(jié)尾?

SJMPDONE ;循環(huán)結(jié)束NEXT1:CJNEA,B,NEXT2;比較NEXT2:JNC NEXT;A>B,轉(zhuǎn)NEXT繼續(xù)取數(shù)

MOV B,A ;保存較小值

SJMPNEXTDONE:SJMPDONE可以看出,這是一個循環(huán)次數(shù)未知的例題,通過設(shè)定特征值控制循環(huán)結(jié)束條件。第43頁/共86頁3.多重循環(huán)多重循環(huán)又稱之為循環(huán)的嵌套,即在一個循環(huán)結(jié)構(gòu)的循環(huán)體內(nèi),又包含另一個完整的循環(huán)結(jié)構(gòu)。在實際應(yīng)用中,有時一重循環(huán)并不能解決問題,所以循環(huán)的嵌套應(yīng)用還是比較廣泛的。在嵌套循環(huán)的使用中,被嵌套的循環(huán)可以不止一個,并且可以嵌套多層,但不論是哪種情況,內(nèi)層循環(huán)和外層循環(huán)都必須是一個完整的結(jié)構(gòu),不允許有相互交叉的情況出現(xiàn)。即如出現(xiàn)圖4-17(a)所示的情況則是非法的嵌套,而圖4-17(b)所示為正確的嵌套。內(nèi)層循環(huán)外層循環(huán)內(nèi)層循環(huán)外層循環(huán)圖4-17(a)非法嵌套示意圖圖4-17(b)正確嵌套示意圖第44頁/共86頁【例4-12】數(shù)據(jù)排序程序。設(shè)有N個數(shù)據(jù),存于首地址為BLOCK的內(nèi)存單元中,試設(shè)計程序?qū)?shù)據(jù)從小到大按升序排列。分析:數(shù)據(jù)排序的方法很多,這里采用沉底法。沉底法的基本思想:通過相鄰兩個數(shù)之間的比較和交換,使排序碼(數(shù)值)較小的數(shù)逐漸從底部移向頂部,排序碼較大的數(shù)逐漸從頂部移向底部,就像較大的數(shù)往下沉底一樣,故而得名。設(shè)由R0為數(shù)據(jù)存放區(qū)的首地址,則(R0+N)中存放第N個數(shù)據(jù),進行沉底排序的過程可以描述為:(1)首先將相鄰的(R0)與(R0+1)進行比較,如果(R0)的值小于(R0+1)的值,則不交換兩者的位置,否則不交換,即使較小的上浮,較大的下沉;接著比較(R0+1)與(R0+2),同樣的方法使小的上浮,大的下沉。依此類推,直到比較完(R0+N-1)和(R0+N)后,(R0+N)為具有最大排序碼(數(shù)值)的元素,稱第一趟排序結(jié)束。(2)然后在(R0+N-1)~R0區(qū)間內(nèi),重新進行第二趟排序,使剩余元素中排序碼最大的元素沉底到(R0+N-1);重復(fù)進行n-1趟后,整個排序過程結(jié)束。其算法流程圖如圖4-18所示。第45頁/共86頁開始外循環(huán)次數(shù)→R4內(nèi)循環(huán)次數(shù)→R3(R0)<(R0+1)(R0)←→(R0+1)R0←R0+1R3←R3—1=0?R4←R4—1=0?循環(huán)結(jié)束YNNNYY第46頁/共86頁ORG1000HBLOCK:DATA20HSORT:MOV A,#N-1 ;N個數(shù)據(jù)排序

MOV R4,A ;外循環(huán)次數(shù)LOOP1:MOV A,R4 MOV R3,A ;內(nèi)循環(huán)次數(shù)

MOV R0,#BLOCK ;設(shè)數(shù)據(jù)指針LOOP2:MOV A,@R0 MOV B,A;B←(R0)

INC R0 MOV A,@R0;A←(R0+1)

CJNEA,B,L1;兩數(shù)比較L1:JNC NEXT ;若B≤A,即(R0)<(R0+1)不交換

DEC R0 ;否則交換數(shù)據(jù)

XCH A,@R0 INC R0;修改數(shù)據(jù)指針

MOV @R0,ANEXT:DJNZR3,LOOP2 ;內(nèi)循環(huán)

DJNZR4,LOOP1 ;外循環(huán)HERE:SJMPHERE在數(shù)據(jù)采集系統(tǒng)中,若被采集的信號變化較慢,經(jīng)常采用中值濾波的方法去掉由于偶然因素造成的干擾誤差。中值濾波時,首先將采樣數(shù)據(jù)排序,再取中間值作為本次采樣的終值。第47頁/共86頁4.2.4子程序設(shè)計第三章指令系統(tǒng)中已經(jīng)介紹過子程序的概念與相關(guān)指令。子程序是一種重要的程序結(jié)構(gòu),主要由需要反復(fù)執(zhí)行的操作或程序段構(gòu)成,以供主程序調(diào)用。另外,子程序也可嵌套,即子程序調(diào)用子程序,只要堆棧深度足夠,子程序可嵌套多層。主程序與子程序以及子程序嵌套調(diào)用的關(guān)系如圖4-19所示。第48頁/共86頁與一般程序的編寫方法相比,子程序具有以下幾個特點。(1)子程序應(yīng)命名。子程序入口即子程序的第一條指令應(yīng)加標(biāo)號作為子程序名,以便主程序調(diào)用。(2)子程序中應(yīng)注意堆棧的使用,以保護和恢復(fù)現(xiàn)場。在有些情況下,若子程序需要改變主程序中某些寄存器或存儲單元的結(jié)果,而這些結(jié)果又不能被修改或在子程序調(diào)用之后仍然需要則應(yīng)在子程序中首先將這些內(nèi)容使用進棧指令保護,在子程序返回之前使用出棧指令恢復(fù)現(xiàn)場。(3)子程序的結(jié)尾必須為子程序返回指令RET,并保證堆棧棧頂為調(diào)用程序的返回地址。(4)子程序嵌套時應(yīng)考慮堆棧的深度。(5)能夠正確傳送參數(shù)。參數(shù)分為入口與出口參數(shù)。所謂入口參數(shù),即調(diào)用子程序之前,需要傳給子程序的參數(shù)。所謂出口參數(shù),即子程序返回時應(yīng)送回調(diào)用程序的結(jié)果參數(shù)。應(yīng)根據(jù)具體情況選擇不同的參數(shù)傳遞方式,通常使用寄存器、存儲器或堆棧的方式傳送參數(shù)。(6)子程序應(yīng)具有一定的功能和通用性。對于操作數(shù)應(yīng)盡量使用以地址或寄存器形式給出,一般不針對具體的數(shù)據(jù)編寫子程序。(7)為了便于調(diào)用,子程序應(yīng)提供足夠的信息。如:子程序名、子程序功能、入口參數(shù)和出口參數(shù)、子程序占用的硬件資源、子程序中調(diào)用的其他子程序名。第49頁/共86頁【例4-13】編程實現(xiàn)C=a2+b2。設(shè)a、b均小于10且分別存于外部RAM的100H,101H單元,要求運算結(jié)果C存于外部RAM102H單元。分析:本題可利用子程序完成求單字節(jié)數(shù)據(jù)的平方,然后通過調(diào)用子程序求出a2和b2。其具體程序如下:SQR:INCAMOVCA,@A+PC;使用查表指令求平方RETTAB:DB0,1,4,9,16,25,36,49,64,81可以看出SQR子程序的入口參數(shù)為A,即將要求平方值的數(shù)送入A;其出口參數(shù)也為A,即求出的平方值也送入A。該例的主程序如下:ORG1000HSTART:MOVDPTR,#0100HMOVXA,@DPTR;取a的值A(chǔ)CALLSQR;調(diào)用子程序求a的平方MOVR1,A;R1←a2MOVDPTR,#0101HMOVXA,@DPTR;取b的值A(chǔ)CALLSQR;調(diào)用子程序求b的平方ADDA,R1;A←a2+b2MOVDPTR,#0102HMOVX@DPTR,A;存結(jié)果

SJMP$第50頁/共86頁【例4-14】設(shè)計子程序?qū)巫止?jié)數(shù)據(jù)對半拆分,變成2個字節(jié)存放。分析:子程序入口參數(shù):累加器A,即將要拆分的數(shù)據(jù)送入A累加器中。出口參數(shù):R1,即將拆分后的數(shù)據(jù)存入(R1)指向的兩個相鄰地址單元。FEN1:MOV@R1,#0;將(R1)指向的地址單元清零

XCHDA,@R1 ;低半字節(jié)存入指定單元

INCR1 ;修改指針,指向下一個地址單元

MOV@R1,#0;清零

SWAPA;高低半字節(jié)交換

XCHDA,@R1 ;保存高半字節(jié)

RET第51頁/共86頁【例4-15】編寫將累加器A中的ASCII碼轉(zhuǎn)換為1位十六進制數(shù)的子程序。分析:十六進制數(shù)0~9的ASCII碼為30H~39H,即十六進制數(shù)(0~9)=ASCII碼-30H;十六進制數(shù)A~F的ASCII碼為41H~46H,即十六進制數(shù)(A~F)=ASCII碼-37H。根據(jù)此對應(yīng)關(guān)系,子程序可編寫如下:ASCHEX:CLRC;準(zhǔn)備相減

SUBBA,#30H;A←A-30HCJNEA,#0AH,L2;轉(zhuǎn)移判斷L2:JCL1;若A中的值<0AH則求得十六進制數(shù)

SUBBA,#07H;若A中的值≥0AH,則A←A-07H,求得十六進制數(shù)L1:RET可以看出該子程序的入口參數(shù)為累加器A,出口參數(shù)也為累加器A。第52頁/共86頁另外,根據(jù)ASCII碼和十六進制數(shù)的對應(yīng)關(guān)系,將1位十六進制數(shù)轉(zhuǎn)換為ASCII碼的程序可編寫如下:HEXASC:CJNEA,#0AH,L1 L1:JNC L2 ADD A,#30H SJMP HERE L2:ADD A,#37H HERE: RET

請讀者自行分析該子程序每條語句的功能及入口和出口參數(shù)。第53頁/共86頁4.3MCS-51匯編語言實用程序舉例在程序設(shè)計時,通常把需要多次使用的程序段設(shè)計成具有特定功能的子程序,以供調(diào)用,這樣可使程序設(shè)計避免了重復(fù)性的工作,從而使效率提高,而程序也更加靈活。下面將分類介紹一些實用的子程序。4.3.1代碼轉(zhuǎn)換程序【例4-16】將累加器A中的8位二進制數(shù)轉(zhuǎn)換成3位BCD碼。3位BCD碼占用兩個字節(jié),結(jié)果的百位數(shù)存于BAI單元,十位和個位數(shù)占用一個字節(jié)單元SHIGE。分析:可應(yīng)用除法指令實現(xiàn)數(shù)制的轉(zhuǎn)換,將被轉(zhuǎn)換的數(shù)除以100得百位數(shù),再將余數(shù)除以10得十位數(shù),余數(shù)為個位數(shù)。例如:設(shè)要轉(zhuǎn)換得二進制數(shù)據(jù)為0EFH,則0EFH除以100,商=02H,即百位數(shù)為2,余數(shù)=27H,27H除以10,商=03H,即十位數(shù)為3,余數(shù)=09H,即個位數(shù)為9。其具體程序如下:第54頁/共86頁BAI: DATA30HSHIGE: DATA31HBINBCD:MOVB,#100 DIVAB;除以100,A←商,B←余數(shù)

MOVBAI,A;BAI←商

MOVA,#10;

XCHA,B;B中的余數(shù)與A中除數(shù)10互換

DIVAB;余數(shù)除以10,A←商,B←余數(shù)

SWAPA;十位數(shù)交換到A的高半字節(jié)

ORLA,B;與B中的個位組合成一個字節(jié)數(shù)據(jù)

MOVSHIGE,A;十位、個位送入單元SHIGE RET該子程序入口參數(shù):累加器A出口參數(shù):地址單元BAI和地址單元GESHI第55頁/共86頁【例4-17】編寫將多字節(jié)二進制數(shù)轉(zhuǎn)換成BCD碼的子程序。分析:上例中介紹了一種使用除法實現(xiàn)將二進制數(shù)轉(zhuǎn)換成BCD碼的算法,但上述方法一般針對轉(zhuǎn)換數(shù)較小的情況,若被轉(zhuǎn)換數(shù)較大,則該算法需要進行多字節(jié)運算,運算速度較慢,程序效率較低。若用b代表各二進制位數(shù),則有下式成立:BCD=bn-1×2n-1+bn-2×2n-2+…+b1×21+b0×20=(((bn-1×2+bn-2)×2+bn-3)×2+…b1)+b0因此可采用從最高位開始,按十進制運算法則循環(huán)“乘2加次低位”的算法:D=D×2+di。設(shè)子程序入口參數(shù):R0、R7。R0為二進制數(shù)低位字節(jié)地址指針,R7為要轉(zhuǎn)換的二進制字節(jié)數(shù)。出口參數(shù)為:R1。R1為壓縮BCD碼高位字節(jié)地址指針。其流程圖如圖4-20所示。第56頁/共86頁開始R3←二進制位數(shù)二進制數(shù)左移1位BCD×2+進位,調(diào)整R3-1=0?結(jié)束YN存儲單元清零字節(jié)數(shù)R2-1=0?YN第57頁/共86頁具體程序如下:ORG1000HBINBCD:MOVA,R0MOVR5,A;R0→R5MOVA,R1MOVR6,A;R1→R6MOVA,R7;取二進制字節(jié)數(shù)INCA;二進制字節(jié)數(shù)加1→AMOVR3,ACLRAL0:MOV@R1,A;對BCD碼存儲單元清零INCR1DJNZR3,L0MOVA,R7;取二進制字節(jié)數(shù)MOVB,#08MULAB;二進制字節(jié)數(shù)×8→二進制位數(shù)MOVR3,A;二進制位數(shù)→R3圖4-20【例4-17】程序流程圖L3:MOVA,R5MOVR0,A;二進制數(shù)低位字節(jié)地址→R0MOVA,R7MOVR2,A;二進制數(shù)字節(jié)數(shù)→R2CLRCL1:MOVA,@R0;二進制數(shù)左移1位RLCAMOV@R0,AINCR0DJNZR2,L1MOVA,R6;BCD碼地址指針→R1MOVR1,AMOVA,R7MOVR2,AINCR2;BCD碼字節(jié)數(shù)→R2L2:MOVA,@R1;BCD碼×2+CYADDCA,@R1DAAMOV@R1,AINCR1DJNZR2,L2DJNZR3,L3RET第58頁/共86頁【例4-18】編程將4位單字節(jié)BCD碼轉(zhuǎn)換成二進制數(shù)。設(shè)4位BCD碼為D3D2D1D0,子程序入口參數(shù):R0。R0為BCD碼的高位字節(jié)D3地址指針(設(shè)BCD碼的高位在前,低位在后),出口參數(shù)為:R3R4,即轉(zhuǎn)換后的二進制數(shù)存放到寄存器R3R4中。開始R3←0R4←(R0)R3R4←R3R4×10R0←R0+1R3R4←R3R4+(R0)R2-1=0?結(jié)束YNR2←3分析:由于D3D2D1D0的二進制數(shù)可表示成:D3×103+D2×102+D1×101+D0×100=((D3×10+D2)×10+D1)×10+D0,所以算法上可采用循環(huán)“高位×10+次低位”的方法。其流程圖如圖4-21所示。第59頁/共86頁具體程序如下:ORG1000HBCDBIN:MOVR2,#03;R2為計數(shù)器MOVR3,#00HMOVA,@R0;取D3MOVR4,ALOOP:MOVA,R4;R4←R4×10MOVB,#0AHMULABMOVR4,A;R4×10的低位字節(jié)→R4MOVR1,B;R4×10的高位字節(jié)→R1暫存MOVA,R3;R3←R3×10MOVB,#0AHMULABADDA,R1;R3×10的低位字節(jié)+R1→AMOVR3,A;R3←高位字節(jié)INCR0;修改指針MOVA,@R0;取下一個數(shù)ADDA,R4;R3R4+(R0)R3R4MOVR4,AMOVA,R3ADDCA,#00HMOVR3,ADJNZR2,LOOPRET開始R3←0R4←(R0)R3R4←R3R4×10R0←R0+1R3R4←R3R4+(R0)R2-1=0?結(jié)束YNR2←3第60頁/共86頁【例4-19】多字節(jié)二進制數(shù)變補碼子程序。分析:多字節(jié)二進制數(shù)求補,可先將低位字節(jié)取反加1變補,然后將高位字節(jié)依次取反再加上低位字節(jié)求補后的進位即可。設(shè)入口參數(shù)為:R0,存放將要取補的二進制數(shù)的低位字節(jié)指針,R2:字節(jié)數(shù)出口參數(shù)為:R0,取補后數(shù)據(jù)的高位字節(jié)指針具體程序如下:

CPLD:SETBCLOOP:MOVA,@R0;取數(shù)

CPLA;取反

ADDCA,#0;加進位求補

MOV@R0,A;保存轉(zhuǎn)換結(jié)果

INCR0 DJNZR2,LOOP DECR0 RET第61頁/共86頁4.3.2算術(shù)運算程序【例4-20】多字節(jié)無符號BCD碼加/減法運算程序。分析:實現(xiàn)多字節(jié)的加/減法運算,可利用指令A(yù)DDC/SUBB,從低位字節(jié)到高位字節(jié)依次相加或相減,由于是BCD碼運算,所以應(yīng)在加法運算后使用十進制調(diào)整指令DAA。設(shè)子程序入口參數(shù)為:R0、R1和R2,即R0為被加數(shù)或被減數(shù)的低位地址指針,R1為加數(shù)或減數(shù)的低位地址指針,R2為字節(jié)數(shù);出口參數(shù)為:R0,即R0為和或差的低位地址指針。具體程序如下:

ORG1000HADDBCD:CLRCLOOP: MOVA,@R0;取被加數(shù)ADDCA,@R1;與加數(shù)相加DAA;十進制調(diào)整MOV@R0,A;存放結(jié)果INCR0;指向被加數(shù)的下一個字節(jié)INCR1;指向加數(shù)的下一個字節(jié)DJNZR2,LOOPJNCHERE;判斷高字節(jié)是否有進位?若沒有,則結(jié)束MOV@R0,#1;否則將進位加到結(jié)果中HERE:RET由于減法運算與加法類似,只要使用SUBB指令代替ADDC指令即可,請讀者自行分析完成。第62頁/共86頁【例4-21】雙字節(jié)無符號數(shù)乘法。R2R3R7R6R3×R7LHR3×R7R2×R7LR2×R7HR3×R6LR3×R6HR2×R6LR2×R6HR2R3R4R5+×分析:雙字節(jié)二進制無符號數(shù)乘法可利用單字節(jié)乘法指令來實現(xiàn),操作時按照以字節(jié)為單位的豎式乘法運算表來完成。例如設(shè)R2R3為被乘數(shù),R6R7為乘數(shù),乘積為R2R3R4R5,由高到低排列,則豎式運算的算法如圖4-22所示R2R3R7R6R3×R7LHR3×R7R2×R7LR2×R7HR3×R6LR3×R6HR2×R6LR2×R6HR2R3R4R5+×第63頁/共86頁具體程序如下:入口參數(shù):被乘數(shù)在R2、R3中,乘數(shù)在R6、R7中。出口參數(shù):乘積在R2、R3、R4、R5中。MULD:MOVA,R3;計算R3×R7MOVB,R7MULABMOVR4,B;R4=R3×R7HMOVR5,A;R5=R3×R7LMOVA,R3;計算R3×R6MOVB,R6MULABADDA,R4;R3×R7H+R3×R6L→R4MOVR4,ACLRAADDCA,BMOVR3,A;R3×R6H+CY→R3MOVA,R2;計算R2×R7MOVB,R7MULABADDA,R4;R2×R7L+R3×R7H+R3×R6L→R4MOVR4,AMOVA,R3ADDCA,B;R2×R7H+R3×R6H+CY→R3MOVR3,ACLRARLCAXCHA,R2;計算R2×R6MOVB,R6MULABADDA,R3;R2×R7H+R3×R6H+R2×R6L→R3MOVR3,AMOVA,R2ADDCA,B;R2×R6H+CY→R2MOVR2,ARET第64頁/共86頁【例4-22】雙字節(jié)無符號數(shù)除法。分析:對于多字節(jié)除法,不能像多字節(jié)乘法一樣使用單字節(jié)除法指令,通常用的算法是參照手算除法的方法進行“移位相減”:首先判斷被除數(shù)(后為余數(shù))是否大于除數(shù),若成立,則該位商上1,從被除數(shù)(余數(shù))中減去除數(shù);否則,商上0,不減除數(shù)。然后把被除數(shù)的下一位左移到余數(shù)后面,再通過比較其大小決定是否與除數(shù)相減。重復(fù)這個過程知道余數(shù)為0或商的位數(shù)滿足要求為止。通常情況下,若除數(shù)和商均為雙字節(jié),則被除數(shù)為4個字節(jié);若被除數(shù)的2個高位字節(jié)大于或等于除數(shù)則商不能用兩個字節(jié)表示,發(fā)生溢出。因此做除法時應(yīng)首先判斷除數(shù)是否為0或發(fā)生溢出,若溢出則子程序返回,否則進行除法運算。設(shè)有算式:R2R3R4R5÷R6R7,商=R4R5,余數(shù)=R2R3,則其算法流程圖如圖4-23所示。第65頁/共86頁開始B←循環(huán)次數(shù)R2R3R4R5左移1位商上1結(jié)束YNB-1=0?YN除數(shù)=0?R2R3>R6R7?被除數(shù)-除數(shù)夠減?F0←0NYYNFO←1第66頁/共86頁其具體程序如下:入口參數(shù):被除數(shù)為R2R3R4R5,除數(shù)在R6、R7中。出口參數(shù):F0=0時,雙字節(jié)商在R2、R3中,F(xiàn)0=1時溢出或除數(shù)為0。DIVD:MOVA,R6JNZOVER;除數(shù)不為0,轉(zhuǎn)移MOVA,R7JZRE1;除數(shù)為0,置結(jié)束標(biāo)志返回OVER:CLRC;被除數(shù)高2個字節(jié)≥除數(shù)?MOVA,R3SUBBA,R7MOVA,R2SUBBA,R6JCDIV1;若高2個字節(jié)<除數(shù),則轉(zhuǎn)移RE1:SETBF0;否則溢出標(biāo)志置1返回RETDIV1:MOVB,#16;無溢出,作除法DIV2:CLRC;部分商和余數(shù)同時左移一位MOVA,R5RLCAMOVR5,AMOVA,R4RLCAMOVR4,AMOVA,R3圖4-23【例4-22】程序流程圖RLCAMOVR3,AXCHA,R2RLCAXCHA,R2MOVF0,C;保存溢出位CLRCSUBBA,R7;計算(R2R3-R6R7)MOVR1,AMOVA,R2SUBBA,R6JBF0,DIV3;結(jié)果判斷JCDIV4DIV3:MOVR2,A;夠減,存放新的余數(shù)MOVA,R1MOVR3,AINCR5;DIV4:DJNZB,DIV2;商在R4R5中MOVA,R4;將商送到出口參數(shù)R2R3中MOVR2,AMOVA,R5MOVR3,ACLRF0;F0←0,設(shè)置除法完成標(biāo)志RET第67頁/共86頁【例4-23】單字節(jié)整數(shù)平方根運算。分析:求平方根的算法主要有牛頓迭代法、直接法等,這里介紹利用等差數(shù)列求和公式求平方根的算法。等差數(shù)列求和公式:n2=1+3+5+…+(2n-1)(1)對于任一正整數(shù)N,總可以找到這樣的n,使得公式:N=n2+ε(2)成立,其中n為N的平方根,ε為誤差,將(1)式代入(2)式,則有:N=1+3+5+…+(2n-1)+ε因此只要從N中減去1,3,5,…,(2n-1),直到不夠減為止,則減去的奇數(shù)的個數(shù)則為N的平方根的整數(shù)部分。設(shè)子程序入口參數(shù)為:R1,出口參數(shù)為R2,其具體程序如下:

SQRT:MOVR2,#0 CLRCLOOP:MOVA,R2;RLCA;R2×2→AINCA;A加1,求奇數(shù)MOVR4,AMOVA,R1SUBBA,R4;R1-奇數(shù)MOVR1,AJCDONE;不夠減,結(jié)束INCR2

;R2+1→R2SJMPLOOPDONE:RET第68頁/共86頁4.3.3延時程序在單片機應(yīng)用系統(tǒng)中,常常需要用到準(zhǔn)確的延時,一般來說,延時的設(shè)計主要通過兩種途徑實現(xiàn):使用硬件定時器延時或使用軟件延時。這里介紹軟件延時。所謂軟件延時,即通過程序達到延時的目的。具體來說,即設(shè)計一循環(huán)子程序,子程序的功能為用循環(huán)程序?qū)⒅噶钪貜?fù)多次執(zhí)行一些無用的操作以達到延時的目的,通過修改循環(huán)次數(shù),便可獲得不同的延時時間。下面將通過具體的例題介紹延時程序的編寫方法。注意:編寫軟件延時程序時,應(yīng)特別要禁止中斷,否則會影響軟件延時的精度。【例4-24】已知單片機系統(tǒng)的晶振頻率為12MHZ,試設(shè)計一軟件延時程序,延時時間為50ms。程序如下:源程序 機器周期(M)指令執(zhí)行次數(shù)DELAY:MOVR1,#50 11 D1:MOVR2,#M 1R1D2:NOP1R1×R2NOP1R1×R2DJNZR2,D2 2

R1×R2DJNZR1,D1 2R1

RET 21外循環(huán)內(nèi)循環(huán)第69頁/共86頁該例題采用雙重循環(huán)結(jié)構(gòu)來實現(xiàn)延時。程序中內(nèi)循環(huán)次數(shù)以M代替,M的實際數(shù)值可通過延時時間計算得出,現(xiàn)分析如下:機器周期數(shù)是執(zhí)行一條指令所需的時間,所以延時時間可通過下式計算得出:T總=延時子程序總機器周期數(shù)×機器周期。由于該單片機晶振頻率fosc為12MHZ,因此其機器周期tj為:其中,內(nèi)循環(huán)機器周期數(shù)=1+1+2,假定內(nèi)循環(huán)實現(xiàn)延時1ms,則應(yīng)有下式成立:1ms=內(nèi)循環(huán)機器周期數(shù)×機器周期×內(nèi)循環(huán)次數(shù),即1×103=(1+1+2)×1×M,由此得:M=

將M代入子程序中,可計算得出總的機器周期數(shù)為:

((1+1+2)×250+2+1)×50+1+2=50153①②③④其中,①為內(nèi)循環(huán)機器周期數(shù)②為MOVR2,#M和DJNZR1,D1兩條指令的機器周期數(shù)③為外循環(huán)次數(shù)④為MOVR1,#50和RET兩條指令的機器周期數(shù)所以延時時間T總=50153×1μs=50.153ms第70頁/共86頁可以看出,決定延時時間的因素主要有兩個:即循環(huán)次數(shù)與晶振頻率。在晶振頻率一定的情況下,可以通過增大循環(huán)次數(shù)和使用多重循環(huán)的方法增長延時時間。此外,還應(yīng)注意將循環(huán)以外指令所花費的時間計算在內(nèi),否則將影響精度。思考:設(shè)有延時子程序如下,若單片機系統(tǒng)的晶振頻率為6MHZ,請讀者分析它的延時時間。DELAY:MOVR6,#100 D1:MOVR7,#100 D2:NOP

溫馨提示

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

評論

0/150

提交評論