匯編語 言程序設計_第1頁
匯編語 言程序設計_第2頁
匯編語 言程序設計_第3頁
匯編語 言程序設計_第4頁
匯編語 言程序設計_第5頁
已閱讀5頁,還剩81頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第四章匯編語言程序設計回憶:MCS-51單片機系統(tǒng)硬件資源MCS-51單片機指令系統(tǒng)單片機系統(tǒng)應用程序設計:熟悉單片機的硬件原理掌握單片機的匯編指令二者有機的組合,形成系統(tǒng)應用程序提高單片機控制系統(tǒng)的特性和效率:熟悉控制系統(tǒng)本身的硬件結構熟悉編程思路、技巧,掌握編程方法、步驟

4.1匯編語言程序設計方法

4.2簡單和分支程序設計

4.3循環(huán)和查表程序設計

4.4子程序和運算程序設計4.1匯編語言程序設計方法

4.1.1程序設計步驟1、匯編語言程序設計:根據(jù)設計任務要求,采用匯編語言編制程序的過程。2、應用程序設計步驟:1.擬定任務書2.建立數(shù)學模型3.建立算法4.繪制程序流程圖5.編制匯編語言源程序6.上機調(diào)試

注意:匯編調(diào)試需要屢次試驗4.1.2程序結構設計的根本方法匯編語言程序設計根本要求:高質(zhì)量、可讀性好、存儲容量小和執(zhí)行速度快匯編程序結構設計的根本方法:1.簡單程序的設計

2.分支程序設計3.循環(huán)程序設計4.子程序設計5.查表程序設計6.散轉程序設計4.2簡單和分支程序設計4.2.1簡單程序設計[例4.1]

請用51匯編指令編寫程序,將外部RAM單元中40H、41H單元4位BCD數(shù)轉換成ASCII碼,送到內(nèi)部RAM單元80H

83H之中。簡單程序:是指程序設計中沒有使用轉移類指令的程序段。也稱順序程序或直線程序。程序執(zhí)行:按照指令存儲位置的先后順序依次執(zhí)行,中間不會有任何分支程序、循環(huán)程序等。程序特點:結構簡單,易于閱讀理解,大量使用數(shù)據(jù)傳送指令。解:根據(jù)ASCII字符表,十進制數(shù)09的ASCII碼和它的BCD碼之間僅相差30H,此題需要把一個字節(jié)的兩位BCD數(shù)進行拆分,然后分別和30H相加,即得到相應的ASCII碼。參考設計程序如下:

ORG1000HADDR1DATA0040HADDR2EQU80H

MOVDPTR,#ADDR1;源地址=>DPTRMOVR0,#ADDR2;目標地址=>R0

MOV@R0,#00H;目標地址單元清零MOVXA,@DPTR;源地址單元中BCD數(shù)送AMOVB,AANLA,#0FHORLA,#30H;完成低位BCD數(shù)轉換MOV@R0,A;存入80HINCR0MOVA,BANLA,#0F0HSWAPA;高位BCD數(shù)送低4位ORLA,#30H;完成高位BCD數(shù)轉換

MOV@R0,A;存入81H

INCR0MOV@R0,#00H;目標地址單元清零INCDPTRMOVXA,@DPTR;源地址單元中第二個BCD數(shù)送AMOVB,AANLA,#0FHORLA,#30H;完成低位BCD數(shù)轉換MOV@R0,A;存入82HINCR0MOVA,BANLA,#0F0HSWAPA;高位BCD數(shù)送低4位ORLA,#30H;完成高位BCD數(shù)轉換

MOV@R0,A;存入83HSJMP$

END4.2.2分支程序設計

分支程序的特點是程序中含有轉移指令。由于轉移指令有無條件轉移和條件轉移之分,因此分支程序也可分為無條件分支程序和條件分支程序兩類。無條件分支程序中含有無條件轉移指令,因簡單這里不作專門討論;條件分支程序中含有條件轉移指令,是我們討論的重點。條件分支程序表達了計算機執(zhí)行程序時的分析判斷能力。假設某種條件滿足,那么機器就轉移到另一分支上執(zhí)行程序;假設條件不滿足,那么機器就按原程序繼續(xù)執(zhí)行。MCS-51中,條件轉移指令共有13條,分為累加器A判零條件轉移、比較條件轉移、減1條件轉移和位控制條件轉移等四類。[例4.2]VAR單元內(nèi)有一自變量X,請按如下條件編出求函數(shù)值Y并將它存入FUNC單元的程序。Y=

解:這是一個三分支歸一的條件轉移問題,程序?qū)崿F(xiàn)通??煞譃椤跋确种Ш筚x值〞和“先賦值后分支〞兩種求解方法?,F(xiàn)分述如下:1.先分支后賦值。題意告訴我們,自變量X是個帶符號數(shù),可采用累加器判零條件轉移和位控制條件轉移指令來實現(xiàn),程序流程如圖4-1(a)所示。相應程序為:ORG1000HVARDATA30HFUNCDATA31HMOVA,VAR;X送AJZDONE;假設X=0,那么轉DONEJNBACC.7,POSI;假設X>0,那么轉POSIMOVA,#0FFH;假設X<0,那么-1送ASJMPDONE;轉DONEPOSI:MOVA,#01H;1送ADONE:MOVFUNC,A;存Y值SJMP$END

A←XA=0?A>0?

A←1

存結果A←

1(a)先分支后賦值

YN

N

Y

圖4-1[例4.2]流程圖

2.先賦值后分支。先把X調(diào)入累加器A,并判斷它是否為零?假設X=0,那么A中內(nèi)容送FUNC單元;假設X≠0,那么先給R0賦值〔如-1〕,然后判斷A<0?假設A<0,那么R0送FUNC單元;假設A>0,那么把R0修改成1后送FUNC單元,程序流程如圖4-1(b)所示。(b)先賦值后分支

A←X,R0←0

R0←1

存結果

R0←–1A=0?

A>0?YN

YN

圖4-1[例4.2]流程圖

相應程序為:ORG1000HVARDATA30HFUNCDATA31HMOVR0,#00HMOVA,VAR;X送AJZDONE;假設X=0,那么轉DONEMOVR0,#0FFH;假設X≠0,那么-1送R0JBACC.7,DONE;假設X<0,那么轉DONEMOVR0,#01H;假設X>0,那么1送R0DONE:MOVFUNC,R0;存Y值SJMP$END[例4.3]某系有200名學生參加外語統(tǒng)考,假設成績已存放在MCS-51外部RAM始地址為ENGLISH的連續(xù)存儲單元,現(xiàn)決定給成績在95分~100分之間學生頒發(fā)A級合格證書和成績在90分~94分之間學生頒發(fā)B級合格證書。試編制一個程序,可以統(tǒng)計A級和B級證書的學生人數(shù),并把統(tǒng)計結果存入內(nèi)部RAM的GRADA和GRADB單元。解:這是一個循環(huán)和分支相結合程序,程序流程圖如圖4-2所示。

圖4-2[例4.3]程序流程圖

A≥95?

A≥90?完成否?GRADB單元內(nèi)容加1修改DPTR指針

結束GRADA單元內(nèi)容加1GRADA和GRADB單元清零、DPTR置初值ENGLISH、循環(huán)計數(shù)器R2置初值200取某學生外語成績YYNNYN相應程序為:ORG1000HENGLISHDATA2000HGRADADATA20HGRADBDATA21HMOVGRADA,#00H;GRADA單元清零MOVGRADB,#00H;GRADB單元清零MOVR2,#0C8H;參考總人數(shù)送R2MOVDPTR,#ENGLISH;學生成績始地址送DPTRLOOP:MOVXA,@DPTR;取某學生成績到ACJNEA,#5FH,LOOP1;和95作比較,形成CyLOOP1:JNCNEXT1;假設A≥95,那么NEXT1CJNEA,#5AH,LOOP2;和90作比較LOOP2:JCNEXT;A<90,NEXTINCGRADB;為B級,那么GRADB單元內(nèi)容加1SJMPNEXTNEXT1:INCGRADA;A≥95,那么GRADA單元內(nèi)容加1NEXT:INCDPTR;修改學生成績指針DJNZR2,LOOP;未完,那么LOOPSJMP$;結束END4.2.3散轉程序設計在利用MCS-51單片機指令設計匯編程序時,有時會遇到一類多分支程序的設計。分支轉移的目標地址不是匯編或編程時確定的,而是在程序運行時動態(tài)決定的。MCS-51單片機提供了間接轉移指令JMP@A+DPTR,恰好可以實現(xiàn)這一類轉移。其中,DPTR裝入多分支轉移程序的首地址,用累加器A的內(nèi)容來動態(tài)選擇其中的某一個分支予以轉移。這樣一條指令可實現(xiàn)以DPTR內(nèi)容為起始地址的256個字節(jié)范圍的選擇轉移。[例4.4]通過調(diào)用鍵盤控制程序KEYREAD可將按下的按鍵鍵值0~15之一讀到累加器A,要求編寫程序?qū)ψx入的不同鍵值,分別轉入對應的鍵控程序段KEY0~KEY15執(zhí)行。即要求:當(A)=0時,轉鍵控處理程序KEY0;當(A)=1時,轉鍵控處理程序KEY1;…………………當(A)=15時,轉鍵控處理程序KEY15。解:對于上述要求的問題,編寫程序如下:ORG1000HACALLKEYREAD;讀鍵值程序RLA;調(diào)整MOVDPTR,#TABLE;表首址送DPTRJMP@A+DPTR;以A中內(nèi)容為偏移量跳轉……………TABLE:AJMPK0;讀入鍵為第1個鍵,轉K0執(zhí)行AJMPK1;讀入鍵為第2個鍵,轉K1執(zhí)行……………AJMPK15;讀入鍵為第16個鍵,轉K15執(zhí)行……………K0:[第1鍵處理程序段]K1:[第2鍵處理程序段]………

K15:[第16鍵處理程序段]4.3循環(huán)和查表程序設計4.3.1循環(huán)程序設計

循環(huán)程序的特點是程序中含有可以重復執(zhí)行的程序段,該程序段通常稱為循環(huán)體。例如,求100個數(shù)的累加和是沒有必要連續(xù)安排100條加法指令的,可以只用一條加法指令并使之循環(huán)執(zhí)行100次。循環(huán)程序的組成〔四局部〕:1.循環(huán)初始化循環(huán)初始化程序段位于循環(huán)程序開頭,用于完成循環(huán)前的準備工作,例如:循環(huán)體中循環(huán)計數(shù)器和各工作存放器設置初值,其中循環(huán)計數(shù)器用于控制循環(huán)次數(shù)。循環(huán)程序設計不僅可以大大縮短所編程序長度和使程序所占存儲單元數(shù)最少,也能使程序結構緊湊和可讀性變好。

應注意循環(huán)程序設計并不能縮短完成任務的程序執(zhí)行時間。2.循環(huán)處理這局部程序位于循環(huán)體內(nèi),是循環(huán)程序的工作程序,需要重復執(zhí)行。要求編寫得盡可能簡練,提高程序執(zhí)行速度。3.循環(huán)控制循環(huán)控制程序也在循環(huán)體內(nèi),常常由修改循環(huán)計數(shù)器內(nèi)容的語句和條件轉移語句等組成,用于控制循環(huán)執(zhí)行次數(shù)。4.循環(huán)結束這局部程序用于存放執(zhí)行循環(huán)程序所得結果以及恢復各工作單元循環(huán)前的初值。循環(huán)程序通常有兩種編制方法:一種是先循環(huán)處理后循環(huán)控制〔即先處理后判斷〕,如圖4-3〔a〕所示;另一種是先循環(huán)控制后循環(huán)處理〔即先判斷后處理〕,如圖4-3〔b〕所示。初始化循環(huán)處理循環(huán)控制循環(huán)結束

完成?初始化循環(huán)處理循環(huán)控制完成?循環(huán)結束(a)先處理后判斷〔b〕先判斷后處理圖4-3循環(huán)程序結構類型[例4.5]內(nèi)部RAM的BLOCK單元開始有一無符號數(shù)據(jù)塊,塊長在LEN單元。請編出求數(shù)據(jù)塊中各數(shù)累加和、并存入SUM單元的程序。

(a)先判斷后處理

(b)先處理后判斷

圖4-4[例4.5]程序流程圖解:為了使讀者對兩種循環(huán)結構有一個全面了解,以便進行分析比較,現(xiàn)給出兩種設計方案。1.先判斷后處理〔見圖4-4(a)〕A←0R2←塊長+1R1←BLOCK

完成?A←(A)+((R1))R1←(R1)+1SUM←和NYA←A+(R1)R1←(R1)+1SUM←和完成?A←0R2←塊長R1←BLOCKYN求累加和參考程序:ORG1000HLENDATA20HSUMDATA21HBLOCKDATA22HCLRA;A清零MOVR2,LEN;塊長送R2MOVR1,#BLOCK;塊始地址送R1INCR2;塊長+1SJMPCHECKLOOP:ADDA,@R1;A+(R1)送AINCR1;修改數(shù)據(jù)塊指針R1CHECK:DJNZR2,LOOP;假設未完,那么轉LOOPMOVSUM,A;存累加和SJMP$END2.先處理后判斷〔見圖4-4(b)〕參考程序為:ORG1000HLENDATA20HSUMDATA21HBLOCKDATA22HCLRA;A清零MOVR2,LEN;塊長送R2MOVR1,#BLOCK;數(shù)據(jù)始地址送R1NEXT:ADDA,@R1;A+(R1)送AINCR1;修改數(shù)據(jù)塊指針R1DJNZR2,NEXT;假設未完,那么轉NEXTMOVSUM,A;存累加和SJMP$END應當注意:上述兩個程序是有區(qū)別的。假設塊長≠0,那么兩個程序的執(zhí)行結果相同;假設塊長=0,那么先處理后判斷程序的執(zhí)行結果是錯誤的?;蛘哒f,先處理后判斷程序至少執(zhí)行一次循環(huán)體內(nèi)程序。[例4.6]設單片機MCS-51內(nèi)部RAM起始地址為30H的數(shù)據(jù)塊中有64個無符號數(shù)。試編制一個程序能使它們按從小到大數(shù)據(jù)排列。解:設有64個無符號數(shù),在數(shù)據(jù)塊中序號為:e64,e63,…,e2,e1,使它們按從小到大順序排列的方法頗多?,F(xiàn)以氣泡分類法為例加以介紹。氣泡分類法又稱兩兩比較法。它先使e64和e63比較,假設e64>e63,那么兩個存貯單元中內(nèi)容交換,反之就不交換;然后使e63和e62相比,按同樣原那么決定是否交換;一直比較下去;最后完成e2和e1比較及交換,經(jīng)過N-1=63次比較〔常用內(nèi)循環(huán)63次來實現(xiàn)〕后,e1位置上必然得到數(shù)組中的最大值,猶如一個氣泡從水底冒到了水頂,如圖4-5所示。第二次冒泡過程和第一次冒泡過程完全相同,比較次數(shù)也可以是63次〔其實只需62次〕,冒泡后可以在e2位置上得到次最大值,如圖4-5所示。冒泡循環(huán)次數(shù)計算:〔以64個數(shù)的排序為例〕大循環(huán)〔外循環(huán)〕共63次;內(nèi)循環(huán):共63×63次。完成64個數(shù)的排序需要外循環(huán)63次、內(nèi)循環(huán)3969次。第一次冒泡排序〔比較5次〕N=6時比較1比較2比較3比較4比較5e144444256e211112564e300025611e44242256000e53625642424242e62563636363636第二次冒泡排序〔比較4次〕N=6時比較1比較2比較3比較4e1256256256256256256e244444242e31114244e40042111e542420000e6363636363636第三次冒泡排序〔比較3次〕N=6時比較1比較2比較3e1256256256256256256e2424242424242e3444363636e41136444e50361111e63600000第四次冒泡排序〔比較2次〕N=6時比較1比較2e1256256256256256256e2424242424242e3363636363636e4444444e5111111e6000000第五次冒泡排序〔比較1次〕N=6時比較1e1256256256256256256e2424242424242e3363636363636e4444444e5111111e6000000其實,64個無符號數(shù)的數(shù)組排序需要冒泡63次的時機是很少的,每次冒泡所需的數(shù)據(jù)比較次數(shù),也是從63逐次減少〔每冒一次泡減少一次比較〕。為了禁止那些不必要的冒泡次數(shù),人們常常設置一個“交換標志位〞?!敖粨Q標志位〞在循環(huán)初始化時清零,在數(shù)據(jù)交換時置位成1〔表示冒泡中進行過數(shù)據(jù)交換〕。“交換標志位〞用來控制是否再需要冒泡:假設“交換標志位〞為1,那么說明剛剛進行的冒泡中發(fā)生過數(shù)據(jù)交換〔即排序尚未完成〕,應繼續(xù)進行冒泡;假設“交換標志位〞為0,那么說明剛進行完的冒泡中未發(fā)生過數(shù)據(jù)交換〔即排序已完成〕,冒泡應該禁止。例如,對于一個已經(jīng)排好序的數(shù)組:1,2,3,…,63,64,排序程序只要進行一次冒泡便可根據(jù)“交換標志位〞狀態(tài)而結束排序程序的再執(zhí)行,這自然可以節(jié)省63-1=62次的冒泡時間。冒泡程序流程如圖4-6所示。圖4-6冒泡程序流程圖

Y開始數(shù)據(jù)塊始址送R0塊長-1送R2“交換標志位”7FH清零eN送20H和A修改數(shù)據(jù)指針eN-1送21HeN≥eN-1?“交換標志”7FH=1?eN和eN-1在數(shù)據(jù)塊中位置交換“交換標志”7FH置”1”結束R2-1=0?NNYYN參考程序為:ORG1000HBUBBLE:MOVR0,#30H;置數(shù)據(jù)塊指針R0MOVR2,#64;塊長送R2CLR7FH;交換標志2FH.7清零DECR2;塊長-1為比較次數(shù)BULOOP:MOV20H,@R0;eN送20HMOVA,@R0;eN送AINCR0MOV21H,@R0;eN-1送21HCJNEA,21H,LOOP;(20H)和(21H)比較LOOP:JCBUNEXT;假設(20H)<(21H),那么BUNEXTMOV@R0,20H;假設(20H)≥(21H),那么兩者交換DECR0MOV@R0,21HINCR0;恢復數(shù)據(jù)塊指針SETB7FH;置“1〞交換標志位BUNEXT:DJNZR2,BULOOP;假設一次冒泡未完,那么BULOOPJB7FH,BUBBLE;假設交換標志位為1,那么BUBBLESJMP$;結束END在以上循環(huán)程序的實例中,單循環(huán)程序結構比較簡單,程序每循環(huán)一次,其循環(huán)體就被執(zhí)行一次。雙循環(huán)(或多循環(huán))程序就不同了,外循環(huán)一次內(nèi)循環(huán)執(zhí)行一圈。因此,在雙重循環(huán)和多重循環(huán)程序設計中,內(nèi)層循環(huán)體前應注意安排循環(huán)初始化,內(nèi)外循環(huán)間也不應相互交叉。查表程序設計

查表是根據(jù)存放在ROM中數(shù)據(jù)表格的項數(shù)來查找和它對應的表中值。方法簡便,可縮短程序長度和提高程序執(zhí)行效率。例如:查Y=X2(設X為0~9)的平方表時,可以預先計算出X為0~9時的Y值作為數(shù)據(jù)表格的內(nèi)容,存放在起始地址為DTAB的ROM存儲器中,并使X的值和數(shù)據(jù)表格的項數(shù)〔所查數(shù)據(jù)的實際地址對DTAB的偏移量〕一一對應。這樣,就可以根據(jù)DTAB+X來找到X對應的Y值。采用MCS-51匯編語言進行查表尤為方便,它有兩條專門的查表指令:MOVCA,@A+DPTRMOVCA,@A+PC第一條查表指令采用DPTR存放數(shù)據(jù)表格的起始地址,其查表過程比較簡單。查表前要把數(shù)據(jù)表格起始地址存入DPTR,然后把要求查表的項數(shù)折算成相對數(shù)據(jù)表始地址的偏移量,送入累加器A,最后使用MOVCA,@A+DPTR完成查表。采用MOVCA,@A+PC指令查表,其步驟分為如下三步。(1)使用傳送指令把所查數(shù)據(jù)表格的項數(shù)送入累加器A.(2)使用ADDA,#data指令對累加器A進行修正。data值由下式確定。PC+data=數(shù)據(jù)表起始地址DTAB其中,PC是查表指令MOVCA,@A+PC的下一條指令碼的起始地址。data值實際等于查表指令和數(shù)據(jù)表存放初始地址之間的字節(jié)數(shù)。(3)采用查表指令MOVCA,@A+PC完成查表。查表程序主要用于代碼轉換、代碼顯示、實時值的查表計算和按命令號實現(xiàn)轉移等。

注意:MOVCA,@A+DPTR指令可以實現(xiàn)64K地址范圍內(nèi)的數(shù)據(jù)查尋,而MOVCA,@A+PC指令只能實現(xiàn)256字節(jié)范圍內(nèi)的數(shù)據(jù)查尋。[例4.7]BLOCK1為起始地址的數(shù)據(jù)塊〔數(shù)據(jù)塊長度在LEN單元〕,數(shù)塊中每個存儲單元中的高、低4位分別為兩個十六進制數(shù),請編程把它們轉換為相應ASCII碼,并存放在BLOCK2開始的連續(xù)存儲單元〔低4位ASCII碼在前,高4位ASCII碼在后〕。解:由于每個存儲單元中放有兩個十六進制數(shù),因此每個存儲單元中十六進制數(shù)應分別轉換成ASCII碼。這就需要兩次使用查表指令MOVCA,@A+PC,這兩條查表指令在程序中位置是不相同的,故兩次對PC調(diào)整的值也不相同。在編程時,可以先把整個程序編完,然后再計算兩條加法指令中的data修正值并填入相應位置。相應參考程序為:ORG1000HLENDATA30HBLOCK1DATA31HBLOCK2DATA51HMOVR0,#BLOCK1;BLOCK1送R0MOVR1,#BLOCK2;BLOCK2送R1LOOP:MOVA,@R0;取源數(shù)據(jù)塊中數(shù)ANLA,#0FH;取出低4位ADDA,#17;第一次地址調(diào)整指令字節(jié)數(shù)MOVCA,@A+PC;第一次查表1MOV@R1,A;存第一次轉換結果1MOVA,@R0;重新取出被轉換數(shù)1SWAPA;高4位調(diào)入低4位2ANLA,#0FH;取出低4位2ADDA,#09;第二次地址調(diào)整1MOVCA,@A+PC;第二次查表1INCR1;修改目的數(shù)據(jù)塊指針1MOV@R1,A;存第二次轉換結果1INCR0;修改源數(shù)據(jù)塊指針1INCR1;修改目的數(shù)據(jù)塊指針3DJNZLEN,LOOP;假設未轉換完,那么轉LOOP2SJMP$;結束ASCTAB:DB‘0’,’1’,’2’,’3’,’4’DB‘5’,’6’,’7’,’8’,’9’DB‘A’,’B’,’C’,’D’,’E’,’F’END4.4子程序和運算程序設計子程序和運算程序是實用程序的兩大支柱程序,在匯編語言程序設計中占有極其重要的地位。4.4.1子程序設計

子程序是指完成確定任務并能為其他程序反復調(diào)用的程序段。調(diào)用子程序的程序叫做主程序或稱調(diào)用程序。

只要在主程序中安排程序的主要線索,在需要調(diào)用某個子程序時采用LCALL或ACALL調(diào)用指令,便可從主程序轉入相應子程序執(zhí)行,CPU執(zhí)行到子程序末尾的RET返回指令,即可從子程序返回主程序斷點處執(zhí)行。在工程上,幾乎所有實用程序都是由許多子程序構成的。子程序可以構成子程序庫,集中存放在某一存儲空間,任憑主程序隨時調(diào)用。采用子程序設計能使整個程序結構簡單,縮短程序設計時間,減少對存儲空間的占用。例如:如果某一實用程序需要10次調(diào)用某一子程序,那么只要在主程序的相應地安排10條調(diào)用指令就可以防止把同一子程序編寫10遍,內(nèi)存空間幾乎可以減少9倍子程序的長度。主程序和子程序是相對的,沒有主程序也不會有子程序。同一程序既可以作為另一程序的子程序,也可以有自己的子程序。即子程序是允許嵌套的,嵌套深度和堆棧區(qū)的大小有關??傊映绦蚴且环N能完成某一專用任務的程序段,其資源需要為所有調(diào)用程序共享,因此,子程序在結構上應具有通用性和獨立性,在編寫子程序時應注意以下問題。使用本卷須知:1)子程序的第一條指令地址稱為子程序的始地址或入口地址。該指令前必須有標號,標號應以子程序任務定名,以便一看就一目了然。例如:延時程序常以DELAY作為標號。2)主程序調(diào)用子程序是通過安排在主程序中的調(diào)用指令實現(xiàn)的,子程序返回主程序必須執(zhí)行安排在子程序末尾的一條RET返回指令。3)主程序調(diào)用子程序和從子程序返回主程序,計算機能自動保護和恢復主程序的斷點地址。但對于各工作存放器、特殊功能存放器和內(nèi)存單元中內(nèi)容,如果需要保護和恢復,就必須在子程序開頭和末尾〔RET指令前〕安排一些能夠保護和恢復它們的指令。4)為使所編子程序可以放在64KB內(nèi)存的任何區(qū)域并能為主程序調(diào)用,子程序內(nèi)部必須使用相對轉移指令而不使用其他轉移指令,以便匯編時生成浮動代碼。5)子程序參數(shù)可以分為入口和出口參數(shù)兩類:入口參數(shù)是指子程序需要的原始數(shù),由調(diào)用它的主程序通過約定的工作存放器R0~R7、特殊功能存放器SFR、內(nèi)存單元或堆棧等預先傳送給子程序使用:出口參數(shù)是由子程序根據(jù)入口參數(shù)執(zhí)行程序后獲得的結果參數(shù),應由子程序通過約定的R0~R7、SFR、內(nèi)存單元或堆棧等傳遞給主程序使用。傳送子程序參數(shù)的方法通常有以下幾種:1)利用存放器或片內(nèi)RAM傳送子程序參數(shù)對于某些簡單子程序、入口參數(shù)和出口參數(shù)通常較少。??刹捎帽緜魉蛥?shù)的方式。例如:CPU可以預先在主程序中把乘數(shù)和被乘數(shù)送入R0~R7,轉入乘法子程序執(zhí)行后得到的乘積也可通過R0~R7傳送給主程序。2)利用存放器傳送子程序參數(shù)的地址如果上述方法不太方便,CPU也可在主程序中把子程序入口參數(shù)地址通過R0~R7傳送給子程序,子程序根據(jù)R0~R7中入口參數(shù)地址便可找到入口參數(shù)并對它們進行相應的操作,操作得到的出口參數(shù)也可把它們的地址通過存放器R0~R7傳送給主程序。3)利用堆棧傳送子程序參數(shù)任何符合先進后出或后進先出原那么的片內(nèi)RAM區(qū)都可稱為堆棧。堆棧中數(shù)據(jù)的存取是由堆棧指針SP指示的。因此,堆棧也可用來傳送子程序參數(shù)。例如:CPU可以通過主程序中的PUSH指令把入口參數(shù)壓入堆棧傳送給子程序,子程序的出口參數(shù)也可通過堆棧傳送給主程序。4)利用位地址傳送子程序參數(shù)如果子程序的入口參數(shù)是字節(jié)中的某些位,那么利用本方法傳送入口和出口參數(shù)也有方便之處,傳送參數(shù)過程和上述諸方法類似。子程序參數(shù)的上述傳遞方法也適用于中斷效勞程序的編制。[例4.8]設MDA和MDB內(nèi)有兩個數(shù)據(jù)a和b,請編制出求c=a2+b2并把c送入MDC的程序,設a和b皆為小于10的整數(shù)。解:本程序由兩局部組成:主程序和子程序。主程序通過累加器A傳送子程序的入口參數(shù)a或b,子程序也通過累加器A傳送出口參數(shù)a2或b2給主程序,子程序為求一個數(shù)的平方的通用子程序。相應程序如下:ORG1000HMDADATA20HMDBDATA21HMDCDATA22HMOVA,MDA;入口參數(shù)a送AACALLSQR;求a2MOVR1,A;a2送R1MOVA,MDB;入口參數(shù)b送AACALLSQR;求b2ADDA,R1;a2+b2送AMOVMDC,A;存入MDCSJMP$;結束SQR:ADDA,#01H;地址調(diào)整MOVCA,@A+PC;查平方表RET;返回SQRTAB:DB0,1,4,9,16DB25,36,49,64,81END上述程序采用了查表法求一個數(shù)的平方,并且通過子程序調(diào)用實現(xiàn)了兩個數(shù)的平方求和,值得注意的是,上述程序僅適應兩個數(shù)比較小,兩個數(shù)的平方和不大于用一個字節(jié)的數(shù)據(jù)表示。[例4.9]片內(nèi)RAM中有一個五位BCD碼〔高位在前,低位在后〕,最大不超過65535,始地址在R0中,BCD碼位數(shù)減1〔04H〕已在R2中,請編出把BCD碼轉換為二進制整數(shù)并存入R4R3中〔R4中內(nèi)容為高8位〕中的程序。解:此題只編出子程序,主程序從略。①算法設:五位BCD碼,y為相應的十六位二進制數(shù),那么以下算式成立:

式中,括號內(nèi)的數(shù)可用加法循環(huán)來做,循環(huán)次數(shù)為指數(shù)的冪〔即:BCD位數(shù)減1〕,相應的程序流程圖如圖4-7所示。開始保護現(xiàn)場R4R3R4R3╳10,R0R0+1R4R3R4R3+(R0)R2-1=0?恢復現(xiàn)場結束R4清零,R3萬位BCD碼圖4-7例4-9程序流程

R4R3+((R0))R3R4(R4R3)╳10+((R0))計算過程圖示(R4R3)╳10=(R3×10)H+(R4×10)L(R3×10)L(R3×10)H+(R4×10)L+Cy(R3×10)L+((R0))②參考程序入口參數(shù):BCD字節(jié)地址指針R0,BCD位數(shù)減1在R2中。出口參數(shù):Y值應存于R4R3中〔R4中為高字節(jié)〕。ORG1000HBCDB:PUSHPSW;保護現(xiàn)場PUSHACCPUSHBMOVR4,#00H;R4清零MOVA,@R0MOVR3,A;萬位BCD碼送R3LOOP:MOVA,R3;R3送AMOVB,#10MULAB;(R3)╳10送BAMOVR3,A;MOVA,#10XCHA,B;(B)=10XCHA,R4;(R3)X10高字節(jié)存R4MULAB;(R4)X10送BA

ADDA,R4;{(R4)X10低字節(jié)}+{(R3)X10高字節(jié)}XCHA,R3;A=(R3)X10低字節(jié)INCR0;ADDA,@R0;A={(R3)X10低字節(jié)}+((R0))XCHA,R3;R3={(R3)X10低字節(jié)}+((R0))ADDCA,#00HMOVR4,A;完成R4R3R4R3+〔R0〕DJNZR2,LOOP;假設未完,那么轉LOOP執(zhí)行。POPB;恢復現(xiàn)場POPACCPOPPSWRET;返回程序中,R2中初值為位數(shù)n減1,對于五位BCD碼,R2中初值為4。4.4.2運算程序設計運算程序可分為浮點數(shù)運算程序和定點數(shù)運算程序兩大類。浮點數(shù)就是小數(shù)點不固定的數(shù),其運算通常比較麻煩,常由階碼運算和數(shù)值運算兩局部組成;定點數(shù)就是小數(shù)點固定的數(shù),通常包括整數(shù)、小數(shù)和混合小數(shù)等,其運算比較簡單,但在數(shù)位相同時定點數(shù)的表示范圍比浮點數(shù)的小。以下只介紹定點數(shù)運算程序設計,假設無特別說明,那么所有程序均指定點數(shù)運算程序。1.加減運算程序設計多字節(jié)加、減運算是應用程序設計中經(jīng)常要進行的一種運算,加、減運算程序可以分為無符號多字節(jié)數(shù)加減運算和帶符號多字節(jié)數(shù)加減運算程序兩種。無符號多字節(jié)加減運算程序(1)無符號多字節(jié)加法運算程序的編制已在前面作過介紹,現(xiàn)以多字節(jié)減法程序為例加以介紹。[例4.10]BLOCK1和BLOCK2為起始地址的存儲區(qū)中分別有5字節(jié)無符號被減數(shù)和減數(shù)〔低位在前,高位在后〕。請編制一個減法子程序,令它們相減,并把差值放入BLOCK1為起始地址的存儲單元。解:用減法指令從低字節(jié)開始相減。相應程序為:ORG1000HSBYTESUB:MOVR0,#BLOCK1;被減數(shù)始址送R0MOVR1,#BLOCK2;減數(shù)始址送R1MOVR2,#05H;字長送R2CLRC;Cy清零LOOP:MOVA,@R0;被減數(shù)送ASUBBA,@R1;相減,形成CyMOV@R0,A;存差INCR0;修改被減數(shù)地址指針I(yè)NCR1;修改減數(shù)地址指針DJNZR2,LOOP;假設未完,那么LOOPRETEND帶符號單字節(jié)加減運算程序帶符號單字節(jié)加減運算程序和無符號加減運算程序類似,只是符號位處理上有所差異。[例4.11]設在BLOCK和BLOCK+1單元中有兩個補碼形式的帶符號數(shù)。請編出求兩數(shù)之和,并把它放在SUM和SUM+1單元〔低8位在SUM單元〕的子程序。解:在兩個8位二進制帶符號數(shù)相加時,其和很可能會超過8位數(shù)能表示的范圍而需要采用16位數(shù)形式來表示,因此,在進行加法時,可以預先把這兩個加數(shù)擴張成16位二進制補碼形式,然后對它完成雙字節(jié)相加。例如:加數(shù)和被加數(shù)皆為-98〔補碼為9EH〕時,擴張成16位二進制形式后相加的算式為:-981111111110011110B+)-981111111110011110B-1961111111100111100B

1最高進位位喪失不計,換算成真值顯然也是-196,結果是正確的。因此,一個8位二進制正數(shù)擴張成16位時只要把它的高8位變成全“0〞,一個8位二進制負數(shù)擴張成16位時需要把它的高8位變成全“1〞。據(jù)此,我們在編程時應在加減運算前先對加數(shù)和被加數(shù)進行擴張,然后完成求和。設R2和R3分別用來存放被加數(shù)和加數(shù)高8位,那么相應程序為:ORG1000HSBADD:PUSHACCPUSHPSWMOVPSW,#08H;保護現(xiàn)場MOVR0,#BLOCK;R0指向一個加數(shù)MOVR1,#SUM;R1指向和單元MOVR2,#00H;高位先令其為零MOVR3,#00HMOVA,@R0;一個加數(shù)JNBACC.7,POS1;假設為正數(shù),那么轉POS1MOVR2,#0FFH;假設為負數(shù),那么全“1〞送R2POS1:INCR0;R0指向下一個加數(shù)MOVB,@R0;取第二加數(shù)到BJNBB.7,POS2;假設是正數(shù),那么轉POS2MOVR3,#0FFH;假設是負數(shù),那么全“1〞送R3POS2:ADDA,B;低8位相加MOV@R1,A;存8位和INCR1;R1指向SUM+1單元MOVA,R2ADDCA,R3;完成高8位求和MOV@R1,A;存高8位和POPPSW;恢復現(xiàn)場POPACCRETEND在上述程序中,入口:被加數(shù)存放在BLOCK,加數(shù)存放在BLOCK+1;出口:和的低字節(jié)存放在SUM,和的高字節(jié)存放在SUM+1。參數(shù)傳遞是利用BLOCK、BLOCK+1、SUM和SUM+1單元實現(xiàn)的。根據(jù)本程序,讀者編出帶符號8位數(shù)減法子程序并不困難?!?〕多字節(jié)十進制數(shù)BCD碼減法由于MCS-51指令系統(tǒng)中只有十進制加法調(diào)整指令DAA,也即該指令只有在加法指令〔ADD、ADDC〕后,才能得到正確的結果。為了用十進制加法調(diào)整指令對十進制減法進行調(diào)整,必須采用補碼相加的方法,用9AH減去減數(shù)即得到以十為模的減數(shù)的補碼。[例4.12]多字節(jié)十進制BCD碼減法子程序如下:入口:被減數(shù)低字節(jié)地址在R1,減數(shù)低字節(jié)地址在R0,字節(jié)數(shù)在R2。出口:差〔補碼〕的低字節(jié)地址在R0,字節(jié)數(shù)在R3。07H為符號位,“0〞為正,“1〞為負。原程序為:ORG1000HSBCD:MOVR3,#00H;差字節(jié)數(shù)置0CLR07H;符號位清0CLRC;借位位清0SBCD1:MOVA,#9AH;減數(shù)對100求補碼SUBBA,@R0ADDA,@R1;補碼相加DAA;十進制相加調(diào)整MOV@R0,A;存結果INCR0;地址值增加1INCR1INCR3;差字節(jié)增加1CPLC;進位位求反,以形成正確的借位DJNZR2,SBCD1;未減完,轉SBCD1,繼續(xù)JNCSBCD2;無借位,轉SBCD2SETB07H;有借位,置“1〞符號位SBCD2:RET;返回主程序程序中,減數(shù)求補后與被減數(shù)相加,方可利用DAA指令進行調(diào)整,假設二者相加調(diào)整后結果無進位C=0,實際上表示二者相減有借位;假設二者相加調(diào)整后結果有進位C=1,實際上表示二者相減無借位。為了正確反映其借位情況,必須對其進位標志位C進行求反操作,舉例說明如下:求BCD碼8943H-7649H=?先對低位字節(jié)運算:1

溫馨提示

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

評論

0/150

提交評論