第04章 MCS-51單片機(jī)匯編語言程序設(shè)計(jì)1_第1頁
第04章 MCS-51單片機(jī)匯編語言程序設(shè)計(jì)1_第2頁
第04章 MCS-51單片機(jī)匯編語言程序設(shè)計(jì)1_第3頁
第04章 MCS-51單片機(jī)匯編語言程序設(shè)計(jì)1_第4頁
第04章 MCS-51單片機(jī)匯編語言程序設(shè)計(jì)1_第5頁
已閱讀5頁,還剩44頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、第第4章章 MCS-51單片機(jī)匯編語言程序單片機(jī)匯編語言程序設(shè)計(jì)設(shè)計(jì) 匯編語言具有高效、快捷等特點(diǎn),在中小規(guī)模應(yīng)用軟件中廣泛應(yīng)用。了解常用偽指令的格式、功能及使用方法,掌握順序程序、分支程序、循環(huán)程序、子程序的特點(diǎn)及編寫方法是匯編語言程序設(shè)計(jì)的基礎(chǔ)。順序程序的執(zhí)行次序就是按語句的先后次序執(zhí)行,應(yīng)避免用順序程序?qū)崿F(xiàn)大量重復(fù)操作;分支程序中有比較判斷環(huán)節(jié),應(yīng)注意邏輯正確性;循環(huán)程序中有一部分要反復(fù)執(zhí)行多次,應(yīng)注意避免死循環(huán);子程序是能完成某一特定功能的程序模塊,應(yīng)具有通用性。通常都將常用功能模塊編寫成子程序形式,以提高程序的可讀性和執(zhí)行效率。4.1 概述 程序是完成某一特定任務(wù)的若干指令的有序集合

2、。編寫程序,就要熟悉計(jì)算機(jī)語言。目前計(jì)算機(jī)語言種類繁多,性能各異,大致可分為三類:機(jī)器語言、匯編語言和高級語言。 匯編語言也是一種面向機(jī)器的程序設(shè)計(jì)語言,它用英文字符來代替對應(yīng)的機(jī)器語言。例如用ADD代替機(jī)器語言中的加法運(yùn)算,這些英文字符被稱為助記符。 計(jì)算機(jī)高級語言是一種面向算法、過程和對象的程序設(shè)計(jì)語言,它采用更接近人們習(xí)慣的自然語言和數(shù)學(xué)語言描述算法、過程和對象,如BASIC,C,JAVA等都是常用的高級語言。 4.1.2 匯編語言語句種類及格式匯編語言語句種類及格式 匯編語言語句有三種基本類型:指令語句、偽指令語句和宏指令語句。指令語句:每一個(gè)指令語句都在匯編時(shí)產(chǎn)生一個(gè)目標(biāo)代碼,對應(yīng)著

3、機(jī)器的一種操作?!纠浚篗OV A,05H ;其目標(biāo)代碼為74H 05H。偽指令語句:偽指令語句是一種說明語句,主要是為匯編程序服務(wù)的,在匯編時(shí)沒有目標(biāo)代碼與之對應(yīng),沒有對應(yīng)的機(jī)器操作。【例】:ONE EQU 1 ;其功能為定義ONE的值為1宏指令語句:用以代替匯編語言源程序中重復(fù)使用的程序段而設(shè)置的一種語句,由匯編程序在匯編時(shí)產(chǎn)生相應(yīng)的目標(biāo)代碼。4.1.3 常用偽指令常用偽指令為了便于編程和對匯編語言程序進(jìn)行匯編,各種匯編語言都提供一些特殊的偽指令,由偽指令確定的操作稱為偽操作。 1起始地址說明起始地址說明 格式: ORG nn功能:用于匯編語言源程序或數(shù)據(jù)塊開頭,指出程序段或數(shù)據(jù)塊存儲(chǔ)的起

4、始地址。nn表示16位地址?!纠浚?ORG 1000HMAIN:MOV DPTR,#2000H ORG偽指令規(guī)定了程序段MAIN的起始地址為1000H。2匯編結(jié)束說明匯編結(jié)束說明格式: END 功能:用于匯編語言源程序末尾,指示源程序到此全部結(jié)束。在匯編時(shí),對END后面的指令不予匯編。因此,END語句必須放在整個(gè)程序的末尾,有且只能有一個(gè)。3賦值賦值格式: 字符名 EQU 數(shù)據(jù)或匯編符號 功能:將一個(gè)數(shù)(8位或16位)或匯編符號賦值給所定義的字符名。EQU偽指令中的字符名必須先賦值后使用,故該語句通常放在源程序的開頭?!纠浚篛RG 0000H CH1 EQU 50H CH2 EQU R4

5、MOV A,CHl ;A(50H) , 相當(dāng)于MOV A,50H MOV A,CH2 ; AR4, 相當(dāng)于MOV A,R4 4定義字節(jié)定義字節(jié)格式: 標(biāo)號: DB nl,n2,nn功能:用于定義8位數(shù)據(jù)的存放地址。表示把指令右邊的單字節(jié)數(shù)據(jù)依次存放到以左邊標(biāo)號為起始地址的連續(xù)存儲(chǔ)單元中,通常用于定義數(shù)據(jù)表,程序中使用查表指令將數(shù)據(jù)取出?!纠浚?ORG 1000HMAIN:MOV DPTR,TAB ;取表頭地址 MOV A,R2 ;R2中存放查表指針 MOVC A,ADPTR ;從表中取出數(shù)據(jù)TAB: DB 7FH,6FH,77H,7CH,39H,5EH,79H,61H END5定義字定義字格

6、式為:標(biāo)號: DW nnl,nn2,nnN功能:用于定義16位數(shù)據(jù)的存放地址。DW指令與DB指令相似,都是在內(nèi)存的某個(gè)區(qū)域內(nèi)定義數(shù)據(jù),不同的是DW指令定義的是字,而DB指令定義的是字節(jié)。DW指令表示把指令右邊的雙字節(jié)數(shù)據(jù)依次存入指定的連續(xù)存儲(chǔ)單元中。常用于定義一個(gè)地址表。6位地址賦值位地址賦值格式:字符名稱 BIT 位地址功能:該指令把BIT右邊的位地址賦給左邊的字符名稱。被定義的位地址在源程序中可用符號名稱來表示。也可以用EQU指令來定義位地址變量?!纠浚篛RG 1000HL0BIT P1.1 Ll BIT 20H7定義存儲(chǔ)區(qū)定義存儲(chǔ)區(qū)格式: 標(biāo)號: DS X功能:用于定義從標(biāo)號開始預(yù)留一

7、定數(shù)量的內(nèi)存單元,以備源程序執(zhí)行過程中使用。預(yù)留單元的數(shù)量由X決定?!纠浚?ORG 1000H CDS: DS 08HMAIN:MOV DPTR,1000H END程序匯編到DS語句時(shí),從1000H地址開始預(yù)留8個(gè)連續(xù)地址單元,后面內(nèi)容從1008H地址開始依次存放。4.1.4 匯編語言程序設(shè)計(jì)方法匯編語言程序設(shè)計(jì)方法匯編語言程序設(shè)計(jì)同高級語言程序設(shè)計(jì)一樣,是有章可循的,只要按照一定的方法步驟去做,程序設(shè)計(jì)就會(huì)變成一件輕松愉快的事情,設(shè)計(jì)的程序也會(huì)規(guī)范、清晰、易讀、易懂。使用匯編語言設(shè)計(jì)程序大致上可分為以下幾個(gè)步驟。1. 分析題意,明確要求。2. 確定算法。 3. 畫程序流程圖。 4. 分配內(nèi)

8、存工作單元。 5. 編寫源程序。 6. 程序優(yōu)化。 7. 上機(jī)調(diào)試。 4.2 順序程序設(shè)計(jì)【例】程序初始化。初始化就是為變量、寄存器、存儲(chǔ)單元賦一初值,是最簡單、最常用的操作。如將R0-R3,P1,30H,40H單元初始化為00H,把R4,R5初始化為0FFH。參考程序如下: ORG 0000H ;PC起始地址 LJMP START;轉(zhuǎn)主程序 ORG 0100H;主程序起始地址START:MOV R0,#00H ;初始化 MOV R1,#00H MOV R2,#00H MOV R3,#00H MOV P1,#00H MOV R4,#0FFH MOV R5,#0FFH MOV 30H,#00H

9、MOV 40H,#00HHERE:SJMP HERE;反復(fù)執(zhí)行該指令,相當(dāng)于等待 END用立即數(shù)比較直觀,但用MOV A,#00H ,MOV R0, A 指令賦值,效果更好。【例】【例】 邏輯運(yùn)算。邏輯操作是控制過程中經(jīng)常使用的,掌握邏輯運(yùn)算的特點(diǎn)是提高程序效率的重要途徑。在邏輯運(yùn)算中,進(jìn)位標(biāo)標(biāo)志CY的地位很特殊,它是邏輯累加器,大多數(shù)邏輯操作要通過CY來完成。用程序?qū)崿F(xiàn)圖4-2所示的邏輯電路功能。圖4-2 邏輯電路參考程序如下:ORG 0000H LJMP STARTORG 0100HSTART:MOV P1,#0FFH ;P1口初始化LOOP:MOV C,P1.1 ORL C, P1.2

10、;P1.1與P1.2邏輯或運(yùn)算 CPL C ;取反 ANL C,P1.0 ;C與P1.0邏輯與運(yùn)算 CPL C MOV 07H,C ;暫存于07H單元中 MOV C,P1.3 ANL C,/P1.4 ;P1.3與P1.4的反邏輯與運(yùn)算 CPL C ORL C,07H MOV P1.5,C ;把結(jié)果在P1.5口輸出 SJMP $ END4.3 分支程序設(shè)計(jì)分支程序的主要特點(diǎn)是程序包含有判斷環(huán)節(jié),不同的條件對應(yīng)不同的執(zhí)行路徑。編程的關(guān)鍵任務(wù)是合理選用具有邏輯判斷功能的指令。由于選擇結(jié)構(gòu)程序的走向不再是單一的,因此,在程序設(shè)計(jì)時(shí),應(yīng)該借助程序框圖(判斷框)來明確程序的走向,避免犯邏輯錯(cuò)誤。一般情況下

11、,每個(gè)選擇分支均需單獨(dú)一段程序,并有特定的名字,以便當(dāng)條件滿足時(shí)實(shí)現(xiàn)轉(zhuǎn)移。1單分支選擇結(jié)構(gòu)單分支選擇結(jié)構(gòu)當(dāng)程序的判斷是二選一時(shí),稱為單分支選擇結(jié)構(gòu)。通常用條件轉(zhuǎn)移指令實(shí)現(xiàn)判斷及轉(zhuǎn)移。單分支選擇結(jié)構(gòu)有三種典型表現(xiàn)形式。圖4-3 單分支選擇結(jié)構(gòu)(a)當(dāng)條件滿足時(shí)執(zhí)行分支程序1,否則執(zhí)行分支程序2。(b)當(dāng)條件滿足時(shí)跳過程序段1,從程序段2順序執(zhí)行;否則,順序執(zhí)行程序段1和程序段2。(c)當(dāng)條件滿足時(shí)程序順序執(zhí)行程序段2;否則,重復(fù)執(zhí)行程序段1,直到條件滿足為止。由于條件轉(zhuǎn)移指令均屬相對尋址方式,其相對偏移量rel是個(gè)帶符號的8位二進(jìn)制數(shù),可正可負(fù)。因此,它可向高地址方向轉(zhuǎn)移,也可向低地址方向轉(zhuǎn)移。

12、對于第三種形式,可用程序段1重復(fù)執(zhí)行的次數(shù)作為判斷條件,當(dāng)重復(fù)次數(shù)達(dá)到某一數(shù)值時(shí),停止重復(fù),程序順序往下執(zhí)行。這是分支結(jié)構(gòu)的一種特殊情況,這實(shí)際是循環(huán)結(jié)構(gòu)程序。用這種方式可方便實(shí)現(xiàn)狀態(tài)檢測?!纠浚篖OOP: JB P1.1,LOOP單分支程序一般要使用狀態(tài)標(biāo)志,應(yīng)注意標(biāo)志位的建立。【例】設(shè)a存放在累加器A中,b存放在寄存器B中,若a0,Y=ab;若a0,則Y=ab。 這里的關(guān)鍵是判a是正數(shù),還是負(fù)數(shù);可通過判斷ACC.7確定。ORG 0000HJMP BRORG 0100HBR: JB ACC.7,MINUS;負(fù)數(shù),轉(zhuǎn)到MINUSCLR C ;清進(jìn)位位SUBB A,B;A-BSJMP DON

13、EMINUS:ADD A,B;A+BDONE:SJMP $;等待 END 2多分支選擇結(jié)構(gòu)多分支選擇結(jié)構(gòu)當(dāng)程序的判別輸出有兩個(gè)以上的出口流向時(shí),稱為多分支選擇結(jié)構(gòu)。8051的多分支結(jié)構(gòu)程序還允許嵌套,即分支程序中又有另一個(gè)分支程序。匯編語言本身并不限制這種嵌套的層次數(shù),但過多的嵌套層次將使程序的結(jié)構(gòu)變得十分復(fù)雜和臃腫,以致造成邏輯上的混亂。多分支選擇結(jié)構(gòu)通常有兩種形式,如圖4-4所示。圖4-4 多分支選擇結(jié)構(gòu)8051的散轉(zhuǎn)指令和比較指令均可以實(shí)現(xiàn)多分支轉(zhuǎn)移。散轉(zhuǎn)指令 JMP A+DPTR 比較指令 CJNE A,direct,rel (共有4條)使用散轉(zhuǎn)指令前,先將各分支程序編寫好,存放在程序

14、存儲(chǔ)器中,并將各分支程序的入口地址組成一個(gè)表格放在一起,把表首地址送入DPTR,把子程序的序號放入A中。在8051指令中,還有4條功能極強(qiáng)的比較轉(zhuǎn)移指令:CJNE A,direct,rel ;A內(nèi)容與直接尋址單元內(nèi)容比較,不等轉(zhuǎn)移CJNE A,#data,rel ;A內(nèi)容與立即數(shù)比較,不等轉(zhuǎn)移CJNE Rn,#data,rel ;寄存器內(nèi)容與立即數(shù)比較,不等轉(zhuǎn)移CJNE Ri,#data,rel ;間址單元內(nèi)容與立即數(shù)比較,不等轉(zhuǎn)移這4條指令對指定單元內(nèi)容進(jìn)行比較,當(dāng)不相等時(shí)程序作相對轉(zhuǎn)移,并指出其大小,以備作第二次判斷;若兩者相等,則程序順序執(zhí)行。 【例】散轉(zhuǎn)程序。編寫程序,根據(jù)20H單元中

15、的內(nèi)容轉(zhuǎn)入相應(yīng)的分支,執(zhí)行指定的操作,將結(jié)果存入指定存儲(chǔ)器單元。程序流程框圖如圖4-5所示圖4-5 散轉(zhuǎn)程序流程參考程序 ORG 0000H LJMP MEMS RESULT EQU 0050H ORG 0100HMEMS:MOV A,20H MOV DPTR,#KKKK;散轉(zhuǎn)程序入口地址表首 址 RL A ;分支號乘2,每個(gè)入口地址均為2字節(jié) JMP A+DPTR ;轉(zhuǎn)移END1: SJMP $KKKK:AJMP MEMSP0 ;A=0加法 AJMP MEMSP1 ;A=1減法 AJMP MEMSP2 ;A=2乘法 SJMP MEMSP3 ;A=3除法 SJMP MEMSP4 ;A=4邏輯與

16、 SJMP MEMSP5 ;A=5邏輯或MEMSP0:MOV A,R0 ;相加分支 CLR C ADD A,R1 MOV RESULT,A LJMP END1MEMSP1:MOV A,R0 ;相減分支 CLR C SUBB A, R1 MOV RESULT,A LJMP END1MEMSP2:MOV A,R0 ;乘法分支 MOV B,R1 CLR C MUL AB MOV RESULT,A MOV RESULT+1,B LJMP END1MEMSP3:MOV A,R0 ;除法分支 MOV B,R1 CLR C DIV AB MOV RESULT,A MOV RESULT+1,B LJMP EN

17、D1MEMSP4:MOV A,R0 ;邏輯與分支 ANL A,R1 MOV RESULT,A LJMP END1MEMSP5:MOV A,R0 ;邏輯或分支 ORL A,R1 MOV RESULT,A LJMP END1 END 【例】 兩個(gè)無符號數(shù)比較大小。設(shè)外部RAM單元ST1和ST2中存放兩個(gè)無符號二進(jìn)制數(shù),要找出其中的大數(shù)存入ST3單元中。程序流程框圖如圖4-6所示。圖4-6 求大數(shù)程序流程參考程序如下: ORG 0000H LJMP START ORG 0100HSTART:MOV A,addr1 ;將addr1中內(nèi)容送A CJNE A,addr2,LOOP1 ;兩數(shù)比較,不相等則

18、轉(zhuǎn)LOOP1LOOP3:AJMP $ ;結(jié)束LOOP1:JC LOOP2 ;當(dāng)CY1,轉(zhuǎn)LOOP2 MOV addr3,A ;CY0,(A)(addr2) SJMP LOOP3 ;轉(zhuǎn)結(jié)束 LOOP2:MOV addr3,addr2 ;CY1,(addr2)(A) SJMP LOOP3 END4.4 循環(huán)程序設(shè)計(jì)在實(shí)際應(yīng)用中經(jīng)常會(huì)遇到功能相同,需要多次重復(fù)執(zhí)行某段程序的情況,這時(shí)可把這段程序設(shè)計(jì)成循環(huán)結(jié)構(gòu),這有助于節(jié)省程序的存儲(chǔ)空間,提高程序的質(zhì)量。循環(huán)程序一般由4部分組成。1. 初始化。即設(shè)置循環(huán)過程中有關(guān)工作單元的初始值,如置循環(huán)次數(shù)、地址指針及工作單元清零等。2. 循環(huán)體。即循環(huán)處理部分,

19、完成主要的計(jì)算或操作任務(wù),是重復(fù)執(zhí)行的程序段。 3. 循環(huán)控制。每循環(huán)一次,就要修改循環(huán)次數(shù)、數(shù)據(jù)及地址指針等循環(huán)變量。并根據(jù)循環(huán)結(jié)束條件,判斷是否結(jié)束循環(huán)。 4. 循環(huán)結(jié)束處理。對結(jié)果進(jìn)行分析、處理、保存。 循環(huán)程序結(jié)構(gòu)有兩種,如圖4-7所示。圖4-7 循環(huán)程序結(jié)構(gòu) 圖(a)是“先執(zhí)行后判斷”結(jié)構(gòu),適用于循環(huán)次數(shù)已知的情況。其特點(diǎn)是進(jìn)入循環(huán)后,先執(zhí)行循環(huán)處理部分,然后根據(jù)循環(huán)次數(shù)判斷是否結(jié)束循環(huán)。 圖(b)是“先判斷后執(zhí)行”結(jié)構(gòu),適用于循環(huán)次數(shù)未知的情況。其特點(diǎn)是將循環(huán)控制部分放在循環(huán)的入口處,先根據(jù)循環(huán)控制條件判斷是否結(jié)束循環(huán),若不結(jié)束,則執(zhí)行循環(huán)操作;若結(jié)束,則退出循環(huán)?!纠?0 ms

20、軟件延時(shí)程序。軟件延時(shí)程序一般都是由DJNZ Rn,rel指令構(gòu)成。執(zhí)行一條DJNZ指令需要兩個(gè)機(jī)器周期。軟件延時(shí)程序的延時(shí)時(shí)間主要與機(jī)器周期和延時(shí)程序中的循環(huán)次數(shù)有關(guān),在使用12 MHz晶振時(shí),一個(gè)機(jī)器周期為1s,執(zhí)行一條DJNZ指令需要兩個(gè)機(jī)器周期,即2s。適當(dāng)設(shè)置循環(huán)次數(shù),即可實(shí)現(xiàn)延時(shí)功能。參考程序如下:ORG 0000HLJMP MEMSORG 0100HDEL: MOV R7,#125 ;外循環(huán)次數(shù),該指令為一個(gè)機(jī)器周期DEL1:MOV R6,#200 ;內(nèi)循環(huán)次數(shù)DEL2:DJNZ R6,DEL2 ;2002400s (內(nèi)循環(huán)時(shí)間)DJNZ R7,DEL1 ;0.4 ms12550

21、 ms(外循環(huán)時(shí)間)SJMP $END【例】排序程序。設(shè)在內(nèi)部RAM中存一無符號數(shù)的數(shù)組,其長度為n,起始地址是30H,要求將它們按從大到小排序,排序后仍存放在原區(qū)域中。 按“冒泡法”對n個(gè)數(shù)排序時(shí),可能用不到n-1次循環(huán),排序就結(jié)束了。為了提高排序速度,程序中可設(shè)一交換標(biāo)志位,如10H位,每次循環(huán)中,若有交換則執(zhí)行SETB 10H,表明排序未完成;若無交換,則執(zhí)行CLR 10H,表明排序已經(jīng)完成。每次循環(huán)結(jié)束時(shí),測10H位,判斷排序是否結(jié)束。參考程序如下: ORG 0000H LJMP BUBBLE ORG 0100HBUBBLE:MOV R0,#30H MOV B,#64H CLR 10H

22、 DEC B ;長度計(jì)數(shù)LOOP:MOV A,R0 ;內(nèi)循環(huán)的入口 MOV 20H,A ;暫存,為交換作準(zhǔn)備 INC R0 MOV 21H,R0 CJNE A,21H,BUEU ;若(20H)(21H)轉(zhuǎn)移 BUEU:JNC BUNEXT ;(20H)(21H)轉(zhuǎn)移 MOV A,R0 ;若(20H) (21H)則交換 MOV R0,20H DEC R0 ;使R0退格指向小地址 MOV R0,A INC R0 ;恢復(fù)R0指向大地址 SETB 10H ;置交換標(biāo)志BUNEXT:DJNZ B,LOOP ;內(nèi)循環(huán)是否結(jié)束的判斷 JB 10H,BUBBLE ;判斷標(biāo)志位為1否?外循環(huán)結(jié)束的判斷 END4

23、.5 子程序設(shè)計(jì) 在實(shí)際應(yīng)用中,一些特定的運(yùn)算或操作經(jīng)常使用,例如多字節(jié)的加、減、乘、除處理,代碼轉(zhuǎn)換、字符處理等。如果每次遇到這些運(yùn)算或操作,都重復(fù)編寫程序,不僅會(huì)使程序煩瑣冗長,而且也會(huì)浪費(fèi)編程者大量時(shí)間。因此經(jīng)常把這些功能模塊按一定結(jié)構(gòu)編寫成固定的程序段,存放在內(nèi)存中,當(dāng)需要時(shí),調(diào)用這些程序段。通常將這種能夠完成一定功能、可以被其它程序調(diào)用的程序段稱為子程序。調(diào)用子程序的程序稱為主程序或調(diào)用程序。調(diào)用子程序的過程,稱為子程序調(diào)用,用ACALL addr11和LCALL addr16兩條指令完成。子程序執(zhí)行完后返回主程序的過程稱為子程序返回,用RET指令完成。1.在編寫子程序時(shí)要注意以下幾

24、點(diǎn):在編寫子程序時(shí)要注意以下幾點(diǎn):要給每個(gè)子程序賦一個(gè)名字。它是子程序入口地址的符號,要給每個(gè)子程序賦一個(gè)名字。它是子程序入口地址的符號,便于調(diào)用。便于調(diào)用。明確入口參數(shù)、出口參數(shù)。所謂入口參數(shù),即調(diào)用該子程明確入口參數(shù)、出口參數(shù)。所謂入口參數(shù),即調(diào)用該子程序時(shí)應(yīng)給哪些變量傳遞數(shù)值,放在哪個(gè)寄存器或哪個(gè)內(nèi)存序時(shí)應(yīng)給哪些變量傳遞數(shù)值,放在哪個(gè)寄存器或哪個(gè)內(nèi)存單元,通常稱為參數(shù)傳遞。出口參數(shù)則表明了子程序執(zhí)行單元,通常稱為參數(shù)傳遞。出口參數(shù)則表明了子程序執(zhí)行的結(jié)果存在何處。例如,調(diào)用開平方子程序,計(jì)算。在調(diào)的結(jié)果存在何處。例如,調(diào)用開平方子程序,計(jì)算。在調(diào)用子程序之前,必須先將用子程序之前,必須先

25、將x值送到主程序與子程序的某一值送到主程序與子程序的某一交接處交接處N(如累加器如累加器A),調(diào)用子程序后,子程序從該交接處,調(diào)用子程序后,子程序從該交接處取得被開方數(shù),并進(jìn)行開方計(jì)算,求出的值。在返回主程取得被開方數(shù),并進(jìn)行開方計(jì)算,求出的值。在返回主程序之前,子程序還必須把計(jì)算結(jié)果送到另一交接處序之前,子程序還必須把計(jì)算結(jié)果送到另一交接處M。這。這樣在返回主程序之后,主程序才可能從交接處樣在返回主程序之后,主程序才可能從交接處M得到的值。得到的值。注意保護(hù)現(xiàn)場和恢復(fù)現(xiàn)場。在執(zhí)行子程序時(shí),可能要使用注意保護(hù)現(xiàn)場和恢復(fù)現(xiàn)場。在執(zhí)行子程序時(shí),可能要使用累加器、累加器、PSW或某些工作寄存器,而在

26、調(diào)用子程序之前,或某些工作寄存器,而在調(diào)用子程序之前,這些寄存器中可能存放有主程序的中間結(jié)果,這些中間結(jié)這些寄存器中可能存放有主程序的中間結(jié)果,這些中間結(jié)果在主程序中仍然有用,這就要求在子程序使用這些資源果在主程序中仍然有用,這就要求在子程序使用這些資源之前,要將其中的內(nèi)容保護(hù)起來,即保護(hù)現(xiàn)場。當(dāng)子程序之前,要將其中的內(nèi)容保護(hù)起來,即保護(hù)現(xiàn)場。當(dāng)子程序執(zhí)行完畢,即將返回主程序之前,再將這些內(nèi)容取出,恢執(zhí)行完畢,即將返回主程序之前,再將這些內(nèi)容取出,恢復(fù)到原來的寄存器,這一過程稱為恢復(fù)現(xiàn)場。復(fù)到原來的寄存器,這一過程稱為恢復(fù)現(xiàn)場。保護(hù)現(xiàn)場通常用堆棧來完成。并在子程序的開始部分使用壓棧指令PUSH

27、,把需要保護(hù)的寄存器內(nèi)容壓入堆棧。當(dāng)子程序執(zhí)行結(jié)束,在返回指令RET前邊使用彈棧指令POP,把堆棧中保護(hù)的內(nèi)容彈出到原來的寄存器。要注意,由于堆棧操作是“先入后出”。因此,先壓入堆棧的參數(shù)應(yīng)該后彈出,才能保證恢復(fù)原來的數(shù)據(jù)。為了做到子程序有一定的通用性,子程序中的操作對象,盡量用地址或寄存器形式,而不用立即數(shù)、絕對地址形式。另外,子程序中如含有轉(zhuǎn)移指令,應(yīng)盡量用相對轉(zhuǎn)移指令。2.子程序的調(diào)用與返回子程序的調(diào)用與返回 主程序調(diào)用子程序是通過子程序調(diào)用指令LCALL add16和ACALL add11來實(shí)現(xiàn)的。前者稱為長調(diào)用指令,指令的操作數(shù)部分給出了子程序的16位入口地址;后者為絕對調(diào)用指令,它

28、的操作數(shù)提供了子程序的11位入口地位,此地址與程序計(jì)數(shù)器PC的高5位并在一起,構(gòu)成16位的調(diào)用地址(即子程序入口地址)。它們的功能,首先是將PC中的當(dāng)前值(調(diào)用指令下一條指令地址,稱斷點(diǎn)地址)壓入堆棧(即保護(hù)斷點(diǎn)),然后將子程序入口地址送入PC,使程序轉(zhuǎn)入子程序運(yùn)行。 子程序的返回是通過返回指令RET實(shí)現(xiàn)的。這條指令的功能是將堆棧中返回地址(即斷點(diǎn))彈出堆棧,送回到PC,使程序返回到主程序斷點(diǎn)處繼續(xù)往下執(zhí)行。子程序調(diào)用過程如圖4-8所示圖4-8 子程序調(diào)用過程 主程序在調(diào)用子程序時(shí)要注意以下問題。 在主程序中,要安排相應(yīng)指令來傳遞子程序的入口參數(shù),即提供子程序的入口數(shù)據(jù)。 在主程序中,要安排相

29、應(yīng)的指令,處理子程序提供的出口數(shù)據(jù),即操作結(jié)果。 在主程序中,不希望被子程序更改內(nèi)容的寄存器,也可以在調(diào)用前由主程序安排壓棧指令來保護(hù)現(xiàn)場,子程序返回后再安排彈棧指令恢復(fù)現(xiàn)場。 在主程序中,要正確地設(shè)置堆棧指針。3.子程序嵌套子程序嵌套子程序嵌套是指在子程序執(zhí)行過程中,還可以調(diào)用另一個(gè)子程序。子程序嵌套過程如圖4-9所示。圖4-9 子程序嵌套過程4.子程序的特性子程序的特性編寫子程序應(yīng)注意以下問題:通用性。為使子程序能適應(yīng)各種不同程序、不同條件的調(diào)用,子程序應(yīng)具有較好的通用性??筛?dòng)性??筛?dòng)性是指子程序段可設(shè)置在存儲(chǔ)器的任何地址區(qū)域。假如子程序只能設(shè)置在固定的存儲(chǔ)器地址段,這在編制主程序時(shí)要

30、特別注意存儲(chǔ)器地址空間的分配,防止兩者重疊。為了能使子程序段浮動(dòng),必須在子程序中避免選用絕對轉(zhuǎn)移地址,而應(yīng)選用相對轉(zhuǎn)移類指令,子程序首地址亦應(yīng)采用符號地址。可遞歸和可重入性。子程序能自己調(diào)用自己的性質(zhì),稱為子程序的可遞歸性,而子程序能同時(shí)被多個(gè)任務(wù)(或多個(gè)用戶程序)調(diào)用的性質(zhì),稱為子程序的可重入性。這在比較復(fù)雜的程序中經(jīng)常用到。子程序說明文件。對于通用子程序,為便于各種用戶選用,要求在子程序編制完成后提供一個(gè)說明文件,使用戶不必詳讀源程序,只需閱讀說明文件就能了解子程序的功能及應(yīng)用?!纠?求平方。用程序?qū)崿F(xiàn) Ca2b2。設(shè)a、b均小于10,a存在31H單元,b存在32H單元,把C存入33H單

31、元。因本題兩次用到平方值,所以在程序中采用把求平方編為子程序的方法。子程序名稱:SQR。功能:求X2,通過查平方表來獲得。入口參數(shù):某數(shù)在A中。出口參數(shù):某數(shù)的平方在A中。參考主程序和子程序如下:主程序:ORG 0000HLJMP MAINORG 0100H MAIN: MOV SP,#3FH ;設(shè)堆棧指針(調(diào)用和返回指令要用到堆棧)MOV A,31H ;取a值LCALL SQR ;第一次調(diào)用,求a2MOV R1,A ;a2 值暫存R1中 MOV A,32H ;取b 值LCALL SQR ; 第二次調(diào)用, 求b2 ADD A, R1 ;完成 a2b2MOV 33H,A ;存結(jié)果到33HSJMP

32、 $ ;暫停 子程序:ORG 0200HSQR:ADD A,#01H ;查表位置調(diào)整,RET為一字節(jié)指令MOVC A,A+PC ;查表取平方值RET ;子程序返回TAB: DB 0,1,4,9,16,25DB 36,49,64,81 END求平方的子程序在此采用的是查表法,用偽指令DB將09的平方值以表格的形式定義到ROM中。子程序中A之所以要加1,是因?yàn)镽ET指令占了一個(gè)字節(jié)。4.6 常用程序舉例代碼轉(zhuǎn)換代碼轉(zhuǎn)換【例】十六進(jìn)制數(shù)轉(zhuǎn)換為ASCII碼。設(shè)十六進(jìn)制數(shù)存在A中。數(shù)字09的ASCII碼分別是30H39H;英文大寫字母AF的ASCII碼分別是41H46H??梢姅?shù)字09的ASCII碼值與數(shù)

33、字值相差30H,字母AF的ASCII碼值與其數(shù)值相差37H。轉(zhuǎn)換過程中,先判斷十六進(jìn)制數(shù)是09還是AF,再將相應(yīng)差值補(bǔ)上即可。參考程序如下: ORG 0000HLJMP STARTORG 2000HSTART:MOV R2,A ;將待轉(zhuǎn)換的十六進(jìn)制數(shù)暫存于R2ADD A,#0F6H ;將待轉(zhuǎn)換的十六進(jìn)制數(shù)加246,檢查有無進(jìn)位來判別它是否大于等于10MOV A,R2 ;原十六進(jìn)制數(shù)送到AJNC AD30 ;如無進(jìn)位,加30HADD A, #37H ;有進(jìn)位,加37HAD30:ADD A, #30HSJMP $END2查表程序查表程序?qū)嶋H應(yīng)用中,線性表是一種常用的數(shù)據(jù)結(jié)構(gòu)。查表就是根據(jù)變量X,在

34、表格中查找對應(yīng)的Y值,使Y=F(X)。在8051指令集中,設(shè)有兩條查表指令:MOVC A,ADPTRMOVC A,APC【例】 BCD碼轉(zhuǎn)換為ASCII碼。BCD碼只有00001001十個(gè)代碼,對應(yīng)的ASCII碼為30H39H。它們之間有固定的對應(yīng)關(guān)系,可用計(jì)算法,也可用查表法進(jìn)行轉(zhuǎn)換。設(shè)BCD碼存放在A中,ASCII碼表格存于首地址為TAB的存儲(chǔ)器中。轉(zhuǎn)換程序如下:ORG 0100HTRANS1:MOV DPTR,#TAB;將ASCII碼表首地址置入DPTR MOVC A,A+DPTR ;查表得對應(yīng)的ASCII碼 SJMP $TAB:DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H 3. 數(shù)據(jù)運(yùn)算數(shù)據(jù)運(yùn)算【例】多字節(jié)無符號數(shù)加法。設(shè)被加數(shù)與加數(shù)分別在以ADR1與ADR2為首址的片內(nèi)數(shù)據(jù)存儲(chǔ)器區(qū)域中,自低字節(jié)起,由低到高依次存放;它們的字節(jié)數(shù)為L,要求加得的和放回被加數(shù)的單元。流程框圖如圖4-10所示。 圖4-10 多字節(jié)無符號數(shù)加法流程圖參考程序如下: ORG 0000HLJMP STARTORG 0100HSTART:MOV R0,#ADR1 MOV R

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(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ǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論