版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、第第4章章 匯編語言程序設(shè)計匯編語言程序設(shè)計 4.1 4.1 匯編語言程序設(shè)計概述匯編語言程序設(shè)計概述4.2 4.2 偽指令偽指令4.3 4.3 基本程序結(jié)構(gòu)基本程序結(jié)構(gòu)4.4 4.4 子程序及參數(shù)傳遞子程序及參數(shù)傳遞4.5 4.5 常用程序舉例常用程序舉例 學(xué)習(xí)目標(biāo)學(xué)習(xí)目標(biāo) 1掌握8051匯編語言程序設(shè)計的步驟; 2掌握8051常用偽指令的使用方法; 3熟悉三種基本程序結(jié)構(gòu)及子程序結(jié)構(gòu),學(xué)會匯編語言程序的設(shè)計方法。重點難點重點難點 1分支、循環(huán)程序的設(shè)計要點; 2子程序的設(shè)計及調(diào)用方法4.1 4.1 匯編語言程序設(shè)計概述匯編語言程序設(shè)計概述程序設(shè)計程序設(shè)計 利用計算機語言編寫程序。匯編語言程
2、序設(shè)計匯編語言程序設(shè)計 使用匯編語言來編寫計算機程序,稱為匯編語言源程序。匯編語言程序設(shè)計一般步驟匯編語言程序設(shè)計一般步驟1題意分析確定算法 對需要解決的問題進行認(rèn)真分析,明確題目要完成的任務(wù),弄清現(xiàn)有的條件和目標(biāo)要求,然后確定算法。2繪制程序流程圖流程線流程線 開始或結(jié)束開始或結(jié)束 處理處理判斷判斷 連接連接 3編寫源程序 4. 匯編、調(diào)試 匯編語言程序必須轉(zhuǎn)換為單片機能執(zhí)行的機器碼形式的目標(biāo)程序才能運行,我們把這一過程稱為匯編,進行匯編的程序稱為匯編程序。 將匯編語言程序匯編成目標(biāo)程序后,還要進行調(diào)試,排除程序中的錯誤。只有通過上機調(diào)試并得出正確結(jié)果的程序,才能認(rèn)為是正確的程序。 4.2
3、4.2 偽指令偽指令 偽指令是在機器匯編中告訴匯編程序如何匯編、對匯編過程進行控制的命令。偽指令與匯編語言指令不同,只在源程序中出現(xiàn),不產(chǎn)生任何機器代碼,在程序的運行過程中不起作用,故稱為“偽指令”。 ORG nn 該指令的作用是指明后面的程序或數(shù)據(jù)塊的起始地址, 它總是出現(xiàn)在每段源程序或數(shù)據(jù)塊的開始。 式中, nn為 16 位地址, 匯編時nn確定了此語句后面第一條指令或第一個數(shù)據(jù)的地址,此后的源程序或數(shù)據(jù)塊就依次連續(xù)存放在以后的地址內(nèi), 直到遇到另一個ORG指令為止。 若省略O(shè)RG偽指令,則該程序段從0000H單元開始存放。 1. 匯編起始偽指令匯編起始偽指令 ORG 標(biāo)號標(biāo)號: END
4、地址或標(biāo)號地址或標(biāo)號 格式中標(biāo)號以及END后面的地址或標(biāo)號可有可無。 功能: 提供匯編結(jié)束標(biāo)志。匯編程序遇到 END后就停止匯編, 對 END以后的語句不予處理, 故 END應(yīng)放在程序的結(jié)束處。 2. 匯編結(jié)束偽指令匯編結(jié)束偽指令END 標(biāo)號標(biāo)號: DB 8位二進制數(shù)表位二進制數(shù)表 功能: 把 8 位二進制數(shù)表依次存入從標(biāo)號開始的連續(xù)的存儲單元中。 格式中, 標(biāo)號區(qū)段可有可無, DB指令之后的 8 位二進制數(shù)表是字節(jié)常數(shù)或用逗號隔開的字節(jié)串, 也可以是用引號括起來的ASCII碼字符串 (一個ASCII字符相當(dāng)于一個字節(jié))。3. 定義字節(jié)偽指令定義字節(jié)偽指令DBORG 1000HBUF1: DB
5、 38H, 7FH, 80HBUF2: DB “How are you!” ORG偽指令指定了標(biāo)號BUF1的地址為1000H, 而DB偽指令是將其后的二進制數(shù)表38H, 7FH, 80H依次存放在1000H, 1001H, 1002H 3 個連續(xù)單元之中, BUF2也是一個標(biāo)號, 其地址與前一條偽指令連續(xù), 即從1003H地址單元開始依次存放字符串中各字符的ASCII碼。 例例: 標(biāo)號標(biāo)號: DW 16位字?jǐn)?shù)據(jù)表位字?jǐn)?shù)據(jù)表 該指令的功能與DB相似, 區(qū)別僅在于從指定地址開始存放的是指令中的16位數(shù)據(jù), 而不是字節(jié)串。每個16位數(shù)據(jù)要占兩個存儲單元, 高8 位先存(低位地址), 低 8 位后存(
6、高位地址)。4. 定義字偽指令定義字偽指令DW ORG 1400HDATA1:DW 324AH,3CH3CH00H4AH32H1403H1402H1401H1400H5.5.空間定義偽指令空間定義偽指令DS 標(biāo)號:標(biāo)號: DS 表達式表達式 功能是從標(biāo)號指定的地址單元開始, 在程序存儲器中保留由表達式所指定的個數(shù)的存儲單元作為備用的空間,并都填以零值。 例如, ORG 3000H BUF:DS 50 匯編后,從地址3000H開始保留50個存儲單元作為備用單元。 字符名稱 EQU 數(shù)字或匯編符號 功能: 使指令中的字符名稱賦值于給定的數(shù)字或匯編符號。 使用等值指令可給程序的編制、調(diào)試、修改帶來方
7、便。 注意:由 EQU等值的字符名稱必須先賦值后使用,且在同一個源程序中,同一個標(biāo)號只能賦值一次。6.字符賦值偽指令字符賦值偽指令EQULEN EQU 10SUM EQU 21HBLOCK EQU 22H CLR A MOV R7,#LEN MOV R0,#BLOCKLOOP:ADD A,R0 INC R0 DJNZ R7,LOOP MOV SUM,A END 例例1:閱讀下列程序,體會:閱讀下列程序,體會EQU偽指令的使用。偽指令的使用。功能是:把從22H開始的10個單元的數(shù)據(jù)求和,將結(jié)果保存在21H單元中。7.7.位地址符號定義位地址符號定義BIT 位地址符號名 BIT 位地址表達式 功能
8、是將位地址賦給指定的符號名。其中,位地址表達式可以是絕對地址,也可以是符號地址。 例如, ST BIT P1.0 將P1.0的位地址賦給符號名ST,在其后的編程中就可以用ST代替P1.0。 4.3 4.3 基本程序結(jié)構(gòu)基本程序結(jié)構(gòu)一、順序程序一、順序程序 順序程序是指無分支、無循環(huán)結(jié)構(gòu)的程序,程序的走向是惟一的,程序的執(zhí)行順序與書寫順序完全一致。 1 1數(shù)制轉(zhuǎn)換數(shù)制轉(zhuǎn)換如92H=146D 則其BCD碼為: 00000001 00000100 00000110 例例 將片內(nèi)將片內(nèi)RAM30H單元內(nèi)的無符號二進單元內(nèi)的無符號二進制數(shù)轉(zhuǎn)換為制數(shù)轉(zhuǎn)換為BCD碼數(shù),結(jié)果按高低順序依次存碼數(shù),結(jié)果按高低順
9、序依次存放到放到33H、32H和和31H單元。單元。 ORG 0100HHEX_D: MOV A,30H ;取源數(shù)據(jù)MOV B , #10 DIV AB ;二級制數(shù)除10MOV 31H,B ;將余數(shù)(BCD碼的個位)送31HMOV B , #10 DIV AB ;商繼續(xù)除10MOV 32H,B ;將余數(shù)(BCD碼的十位)送32H MOV 33H,A ;將商(BCD碼的百位)送32HRET方法1:HEXBCD: MOV A, 30H MOV B, 100 DIV AB MOV 33H, A;存BCD碼百位 MOV A, 10 XCH A, B DIV AB MOV 32H, A;存BCD碼十位
10、MOV 31H, B;存BCD碼個位 RET 方法2:2 2查表程序查表程序 例 求R1中數(shù)(015之間)的平方,結(jié)果仍放回R1中。 方法一: ORG 0000HTAB1: MOV A, R1 ADD A, #02H ;加上地址偏移量 MOVC A, A+PC ;查表 MOV R1,A RET DB 00H, 01H, 04H, 09H ;平方表 DB 10H, 19H, 24H, 31H ;續(xù)表 DB 40H, 51H ,100,121,144 DB 169,196,225 ;續(xù)表方法二:方法二: ORG0000HTAB2:PUSHDPH;保存DPTR的原值PUSHDPLMOVDPTR, #
11、TAB;取平方表首地址MOVA, R1MOVC A, A+DPTR;查平方表MOVR1, APOPDPL;恢復(fù)DPTR的原值POPDPHRETTAB:DB00H, 01H, 04H, 09H;平方表DB10H, 19H, 24H, 31HDB40H, 51H二、二、 分支程序分支程序 程序的執(zhí)行是按照指令的書寫順序進行的,但根據(jù)實際需要也可以改變程序的執(zhí)行順序,這種程序結(jié)構(gòu)就屬于分支結(jié)構(gòu)。 分支結(jié)構(gòu)可以分成單分支、雙分支和多分支幾種情況。 單分支結(jié)構(gòu):若條件成立,則執(zhí)行程序段A,然后繼續(xù)執(zhí)行該指令下面的指令;如條件不成立,則不執(zhí)行程序段A,直接執(zhí)行該指令的下條指令。條件滿足嗎?條件滿足嗎?程序
12、段程序段ANY條件滿足嗎?程序段0程序段1NY分支號k=?程序段0程序段1程序段n=0= =1=n 雙分支結(jié)構(gòu):若條件成立,執(zhí)行程序段A;否則執(zhí)行程序段B。 多分支結(jié)構(gòu):先將分支按序號排列,然后按照序號的值來實現(xiàn)多分支選擇。 分支程序常利用條件轉(zhuǎn)移指令實現(xiàn)。即根據(jù)條件對程序的執(zhí)行情況進行判斷,滿足條件則轉(zhuǎn)移,否則順序執(zhí)行。 用于判斷分支轉(zhuǎn)移的指令有:JZ、JNZ、JC、JNC、JB、JNB、JBC、CJNE、DJNZ、JMP A+DPTR等。 例 : 無符號數(shù)的比較 (單分支結(jié)構(gòu)) 比較外部RAM Data1和Data2單元的兩個無符號數(shù),并將大數(shù)存入Data3單元 ( Data1、 Data
13、2 和Data3為3個連續(xù)單元 )第二個數(shù)據(jù)大么?保存較大數(shù)交換兩個數(shù)YN取第一個待比較數(shù)據(jù)取第二個待比較數(shù)據(jù)例 : 無符號數(shù)的比較 (單分支結(jié)構(gòu)) 比較外部RAM Data1和Data2單元的兩個無符號數(shù),并將大數(shù)存入Data3單元 ( Data1、 Data2 和Data3為3個連續(xù)單元 )ORG 1000HCOM1:MOV DPTR,#Data1 ;設(shè)置外部數(shù)據(jù)存儲器指針MOVX A,DPTR;取第一個數(shù)MOV B,A;暫存第一個數(shù)到BINC DPTR;指向第二個數(shù)所在單元MOVX A,DPTR;取第二個數(shù)到ACJNE A,B,L1;兩數(shù)比較,產(chǎn)生Cy標(biāo)志L1:JC BIG1;若第二個數(shù)
14、小于第一個數(shù)BIG:INC DPTR;指向Data3單元MOVX DPTR,A;存大數(shù)RETBIG1:XCH A,B;將大數(shù)轉(zhuǎn)移到ASJMP BIGEND例例 (雙分支結(jié)構(gòu)) x, y均為8位二進制數(shù), 設(shè) x存入R0, y存入R1, 求解: 011y808080 xxxY開始y=-1X=80?結(jié)束NX80?y=0y=+1NYSTART: CJNE R0, 50H, SUL1 ;R0中的數(shù)與80比較不等轉(zhuǎn)移 MOV R1, 00H ; 相等, R1 0 SJMP SUL2 SUL1: JC NEG ; 兩數(shù)不等, 若(R0)0, 則 R101H SJMP SUL2 NEG: MOV R1, 0
15、FFH ; (R0)=0AH,則加37H轉(zhuǎn)換為ASCIIMOVR2, A;保存結(jié)果RET 散轉(zhuǎn)程序是分支程序的一種, 它可根據(jù)運算結(jié)果或輸入數(shù)據(jù)將程序轉(zhuǎn)入不同的分支。 用JMPA+DPTR指令可以很容易地實現(xiàn)散轉(zhuǎn)功能。 特點:轉(zhuǎn)移的目標(biāo)地址不是在編程或匯編時預(yù)先確定的,而是在程序運行過程中動態(tài)地確定的。目標(biāo)地址是以數(shù)據(jù)指針DPTR的內(nèi)容為起始的 256 字節(jié)范圍內(nèi)的指定地址,即由DPTR的內(nèi)容決定分支轉(zhuǎn)移程序的首地址, 由累加器A的內(nèi)容來動態(tài)選擇其中的某一個分支轉(zhuǎn)移程序。 3.散轉(zhuǎn)程序設(shè)計散轉(zhuǎn)程序設(shè)計 (R0)=0 對應(yīng)的分支程序標(biāo)號為PR0; (R0)=1 對應(yīng)的分支程序標(biāo)號為PR1; (R
16、0)=N 對應(yīng)的分支程序標(biāo)號為PRN。 例例 根據(jù)工作寄存器根據(jù)工作寄存器R0 內(nèi)容的不同內(nèi)容的不同, 使程序轉(zhuǎn)入使程序轉(zhuǎn)入相應(yīng)的分支。相應(yīng)的分支。LP0: MOV DPTR, TAB ; 取表頭地址 MOV A, R0 ADD A, R0 ; R0內(nèi)容乘以2 JNC LP1 ; 無進位轉(zhuǎn)移 INC DPH ; 加進位位LP1: JMP A+DPTR; 跳至散轉(zhuǎn)表中相應(yīng)位置TAB: AJMP PR0 AJMP PR1 AJMP PRN 本例程序僅適用于散轉(zhuǎn)表首地址 TAB和處理程序入口地址 PR0, PR1, , PRN在同一個 2 KB范圍的存儲區(qū)內(nèi)的情形。 若超出若超出2KB范圍可在分支程
17、序入口處安排一條范圍可在分支程序入口處安排一條長跳轉(zhuǎn)指令長跳轉(zhuǎn)指令, 可采用如下程序(略講)可采用如下程序(略講): MOV DPTR, TABMOV A, R0 MOV B, 03H MUL ABXCH A, B ADD A, DPHMOV DPH, A XCH A, B JMP A+DPTR TAB: LJMP PR0 LJMP PR1 LJMP PRN 三、三、 循環(huán)程序設(shè)計循環(huán)程序設(shè)計概念:循環(huán)程序是指按某種控制規(guī)律重復(fù)執(zhí)行的程序作用:可以減少指令,節(jié)省存儲單元 循環(huán)程序結(jié)構(gòu)循環(huán)程序結(jié)構(gòu) (1) 初始化部分: 為循環(huán)程序做準(zhǔn)備(2) 處理部分: 是循環(huán)程序的實體, 也是循環(huán)程序的主體。
18、(3)循環(huán)修改部分:修改變量的值 (4)循環(huán)控制部分: 判斷循環(huán)是否結(jié)束,(5)結(jié)束部分:對循環(huán)程序的結(jié)果進行分析、 處理和存放。 循環(huán)程序的形式循環(huán)程序的形式先執(zhí)行后判斷先判斷后執(zhí)行開始開始循環(huán)初始化循環(huán)初始化循環(huán)處理循環(huán)處理循環(huán)修改循環(huán)修改結(jié)束處理結(jié)束處理繼續(xù)循環(huán)?繼續(xù)循環(huán)?結(jié)束結(jié)束NY開始開始循環(huán)初始化循環(huán)初始化循環(huán)處理循環(huán)處理循環(huán)修改循環(huán)修改結(jié)束處理結(jié)束處理循環(huán)結(jié)束?循環(huán)結(jié)束?結(jié)束結(jié)束YN 例例 設(shè)在片外RAM 40H開始的存儲區(qū)中有若干個字符,已知最后一個字符為“$”(并且只有1個),試統(tǒng)計字符的個數(shù)(包括$字符)。結(jié)果存入片內(nèi)30H單元中。 分析:本例是循環(huán)次數(shù)未知的循環(huán)程序。它的
19、結(jié)束條件是查找結(jié)束字符“$”。用R2來統(tǒng)計字符的個數(shù),置初值為0,用R0作為地址指針寄存器。例題分析例題分析方法方法1:先處理后判斷。:先處理后判斷。 開始開始設(shè)地址指針設(shè)地址指針R0初值初值統(tǒng)計個數(shù)單元統(tǒng)計個數(shù)單元R2清清0A片外數(shù)據(jù)(片外數(shù)據(jù)(R0)地址指針地址指針R0+1存字符個數(shù)存字符個數(shù)A=“$”嗎?嗎?結(jié)束結(jié)束YN統(tǒng)計個數(shù)單元統(tǒng)計個數(shù)單元R2+1START: MOV R0,#40H MOV R2,#00H LP: MOVX A,R0 INC R2 INC R0 CJNE A,#24H,LP ;“$”的ASCII碼為24H MOV 30H,R2 ;存結(jié)果 SJMP $ END 方法方
20、法2:先判斷后處理:先判斷后處理 START: MOV R0,#40H MOV R2,#00HLP: MOVX A,R0 CLR C SUBB A,#24H JZ NEXT INC R2 INC R0 SJMP LPNEXT: INC R2 SJMP $ END開始開始設(shè)地址指針設(shè)地址指針R0初值初值統(tǒng)計個數(shù)單元統(tǒng)計個數(shù)單元R2清清0統(tǒng)計個數(shù)單元統(tǒng)計個數(shù)單元R2+1循環(huán)修改地址指針循環(huán)修改地址指針R0+1結(jié)束處理結(jié)束處理A=“$”嗎?嗎?結(jié)束結(jié)束NYA片外數(shù)據(jù)(片外數(shù)據(jù)(R0)R2+1(加(加“$”個數(shù))個數(shù))例例 設(shè)在內(nèi)部設(shè)在內(nèi)部 RAM的的BLOCK單元開始處有長度為單元開始處有長度為LE
21、N個的無符號數(shù)據(jù)塊個的無符號數(shù)據(jù)塊, 試編一個求和程序試編一個求和程序, 并將和存入內(nèi)部并將和存入內(nèi)部 RAM的的SUM單元(設(shè)和不超過單元(設(shè)和不超過8位)。位)。 BLOCK EQU 20H LEN EQU 30H SUM EQU 40HSTART:CLR A ;清累加器A MOV R2, LEN ;數(shù)據(jù)塊長度送R2 MOV R1, BLOCK ;數(shù)據(jù)塊首地址送R1LOOP: ADD A, R1 ;進入循環(huán),實現(xiàn)加法 INC R1 ;修改地址指針 DJNZ R2, LOOP ;修改計數(shù)器并判斷 MOV SUM, A ;存和 RET END 1.單循環(huán)程序單循環(huán)程序 例:用8051單片機的P
22、1口連接的8個發(fā)光二極管模擬廣告流水燈,編程實現(xiàn)8個發(fā)光二極管循環(huán)點亮。 流水燈原理分析流水燈原理分析START:MOV P1,#0FEH ;L1亮MOV P1,#0FDHMOV P1,#0FBHMOV P1,#0F7HMOV P1,#0EFHMOV P1,#0DFHMOV P1,#0BFHMOV P1,#7FHSJMP START循環(huán)點亮發(fā)光二極管程序:循環(huán)點亮發(fā)光二極管程序:START: MOV A,#0FEH LOP: MOV P1,A RL A SJMP LOP END 程序存在的問題:程序存在的問題:程序執(zhí)行得太快,程序執(zhí)行得太快,逐一點亮發(fā)光二極管時逐一點亮發(fā)光二極管時的間隔時間太
23、短,在我的間隔時間太短,在我們看來就是同時點亮了們看來就是同時點亮了!2.多重循環(huán)多重循環(huán)延時程序延時程序所謂延時,就是讓CPU做一些與主程序功能無關(guān)的操作(例如將一個數(shù)字逐次減1直到0)來消耗掉CPU的時間。例如:fosc=6 MHz 則Tcy=12/fosc=2s 執(zhí)行一條DJNZ指令的時間為:2s2=4s 如果執(zhí)行250次,則可延時4s250=1ms。 延時程序?qū)嵗貉訒r程序?qū)嵗豪?-10:設(shè)計一個延時100ms的延時程序,設(shè)單片機時鐘晶振頻率為fosc=6MHz。 分析:要達到延時100 ms,則需執(zhí)行DJNZ指令25000 次。 對于25000次循環(huán)可采用外循環(huán)、 內(nèi)循環(huán)嵌套的多
24、重循環(huán)結(jié)構(gòu)。100ms延時程序延時程序 DELAY: MOV R6, 64H ;1TcyLOOP1: MOV R7, 0F8H ;1 Tcy NOP ;1Tcy LOOP2: DJNZ R7, LOOP2 ; 2Tcy DJNZ R6, LOOP1 ; 2Tcy RET ; 2Tcy 總延時時間: 2s*1+(1+1+2*248+2)*100+2=100.006ms例例. 軟件延時。軟件延時。 設(shè)晶振頻率設(shè)晶振頻率12MHz,則下面的程序段可實現(xiàn),則下面的程序段可實現(xiàn)998 S的延時,用的延時,用子程序調(diào)用指令子程序調(diào)用指令(ACALL、LCALL)調(diào)用,正好是調(diào)用,正好是1mS。 DELAY
25、:MOV R1,#0AH;1 S AGAIN:MOV R2,#30H;1 S DJNZ R2,;2 S DJNZ R1,AGAIN;2 S NOP;1 S NOP;1 S NOP;1 S NOP;1 S NOP;1 S RET;2 S *48=96 *10=990 S 多重循環(huán)的定義多重循環(huán)的定義定義:多重循環(huán)是指在一個循環(huán)程序中又包含一個或多個小的循環(huán),又稱為循環(huán)嵌套。注意:多重循環(huán)中的各重循環(huán)不能交叉,即不能從外循環(huán)跳入內(nèi)循環(huán)。循環(huán)點亮發(fā)光二極管的完整程序循環(huán)點亮發(fā)光二極管的完整程序 START:MOV A,#0FEH LOP: MOV P1,A ACALL DELAY RL A SJMP
26、 LOP DELAY: MOV R6, 64H LOOP1: MOV R7, 0F8H NOP LOOP2: DJNZ R7, LOOP2 DJNZ R6, LOOP1 RET END 4.4 4.4 子程序及參數(shù)傳遞子程序及參數(shù)傳遞 在程序設(shè)計過程中,經(jīng)常會遇到在不同的程序或同一程序的不同地方要求實現(xiàn)某些相同的功能,為簡化程序設(shè)計,縮短程序設(shè)計的周期及程序長度,常把那些頻繁使用的基本操作編成相對獨立的程序段,這些獨立的程序段稱為子程序子程序。在設(shè)計程序時,可以根據(jù)需要調(diào)用這些子程序。一、 子程序的概念 子程序SUB 主程序MAINLCALL SUB 調(diào)用子程序子程序入口地址RET主程序與子程
27、序的關(guān)系主程序與子程序的關(guān)系 子程序的結(jié)構(gòu)與一般的程序并無多大區(qū)別,它的主要特點是,在執(zhí)行過程中需要由其他程序來調(diào)用,執(zhí)行完后又需要把執(zhí)行流程返回到調(diào)用該子程序的主程序。 子程序調(diào)用時要注意兩點:一是現(xiàn)場的保護和恢復(fù);二是主程序與子程序的參數(shù)傳遞。二、二、 現(xiàn)場保護與恢復(fù)現(xiàn)場保護與恢復(fù) 在子程序執(zhí)行過程中常常要用到單片機的一些通用單元,如工作寄存器R0R7、累加器A、數(shù)據(jù)指針DPTR以及有關(guān)標(biāo)志和狀態(tài)等。而這些單元中的內(nèi)容在調(diào)用結(jié)束后的主程序中仍有用,所以需要進行保護,稱為現(xiàn)場保護。在執(zhí)行完子程序,返回繼續(xù)執(zhí)行主程序前恢復(fù)其原內(nèi)容,稱為現(xiàn)場恢復(fù)。 1.1.在主程序中實現(xiàn)在主程序中實現(xiàn)其特點是結(jié)
28、構(gòu)靈活。示例如下:SUB1:PUSH PSW ;保護現(xiàn)場 PUSH ACC PUSH B MOV PSW,#10H;使RS1=1、RS0=0,更換當(dāng)前;工作寄存器組 LCALL ADDR16 ;子程序調(diào)用 POP B ;恢復(fù)現(xiàn)場 POP ACC POP PSW 2 2在子程序中實現(xiàn)在子程序中實現(xiàn)其特點是程序規(guī)范、清晰。SUBl:PUSH PSW ;保護現(xiàn)場 PUSH ACC PUSH B MOV PSW,#10H ;換當(dāng)前工作寄存器組 POP B ;恢復(fù)現(xiàn)場 POP ACC POP PSW RET三、三、 參數(shù)傳遞參數(shù)傳遞 由于子程序是主程序的一部分,所以,在程序執(zhí)行時必然要發(fā)生數(shù)據(jù)上的聯(lián)系。
29、在調(diào)用子程序時,主程序應(yīng)通過某種方式把有關(guān)參數(shù)(即子程序的入口參數(shù))傳給子程序,當(dāng)子程序執(zhí)行完畢后,又需要通過某種方式把有關(guān)參數(shù)(即子程序的出口參數(shù))傳給主程序。 1 1利用累加器或寄存器利用累加器或寄存器 在這種方式中,要把預(yù)傳遞的參數(shù)存放在累加器A或工作寄存器R0R7中。即在主程序調(diào)用子程序時,應(yīng)事先把子程序需要的數(shù)據(jù)送入累加器A或指定的工作寄存器中,當(dāng)子程序執(zhí)行時,可以從指定的單元中取得數(shù)據(jù),執(zhí)行運算。反之,子程序也可以用同樣的方法把結(jié)果傳送給主程序。例:試編程計算例:試編程計算y=ORG0000HMAIN: MOVSP, #60H;堆棧初始化MOVR0, #20H;設(shè)置數(shù)據(jù)指針MOVR
30、7, #10;設(shè)置循環(huán)計數(shù)器MOVR3, #00H;清結(jié)果單元MOVR2, #00HNEXT: MOVA, R0;取數(shù)據(jù)ACALL SQRT;調(diào)用求平方數(shù)子程序ADDA, R3;平方部分和MOVR3, A;保存CLRAADDC A, R2;部分和高字節(jié)加部分和低字節(jié)產(chǎn)生的進位MOVR2, AINCR0;指向下一個數(shù)據(jù)單元DJNZR7, NEXT;未完,繼續(xù)SJMP$1012iiaORG0100H;求平方的子程序SQRT: MOV DPTR, #TAB;取平方表首地址MOVCA, A+DPTR;查平方表RET;子程序返回TAB:DB 0, 1, 4, 9, 16, 25, 36, 49, 64,
31、 81, 100END例例 編寫程序,假設(shè)編寫程序,假設(shè)a、b均小于均小于10,實現(xiàn),實現(xiàn)c=a2+b2,其中,其中a,b,c分別存于內(nèi)部分別存于內(nèi)部RAM的的30H,31H,32H三個單元中。三個單元中。 START:MOV A,30H ;取a ACALL SQR ;調(diào)用SQR子程序,求a2 MOV R1,A MOV A,31H ACALL SQR ADD A,R1 MOV 32H,A SJMP $SQR: MOV DPTR,#TAB;入口參數(shù)和出口參數(shù)均放在A中 MOVC A,A+DPTR RETTAB:DB 0,1,4,9,16,25 DB 36,49,64,81 END 2利用存儲器利
32、用存儲器 當(dāng)傳送的數(shù)據(jù)量比較大時,可以利用存儲器實現(xiàn)參數(shù)的傳遞。在這種方式中,事先要建立一個參數(shù)表,用指針指示參數(shù)表所在的位置。當(dāng)參數(shù)表建立在內(nèi)部RAM時,用R0或R1作參數(shù)表的指針。當(dāng)參數(shù)表建立在外部RAM時,用DPTR作參數(shù)表的指針。 例例 編寫一個子程序,將編寫一個子程序,將R0和和R1指向的內(nèi)部指向的內(nèi)部RAM中兩個中兩個3字節(jié)字節(jié)無符號整數(shù)相加,結(jié)果送到由無符號整數(shù)相加,結(jié)果送到由R0指向的內(nèi)部指向的內(nèi)部RAM中。入口時,中。入口時,R0和和R1分別指向加數(shù)和被加數(shù)的低位字節(jié);出口時,分別指向加數(shù)和被加數(shù)的低位字節(jié);出口時,R0指向結(jié)指向結(jié)果的高位字節(jié)。低字節(jié)在高地址,高字節(jié)在低地址
33、。果的高位字節(jié)。低字節(jié)在高地址,高字節(jié)在低地址。程序段如下:例如: NADD:MOV R7,#3 ;3字節(jié)加法 CLR CNADDl:MOV A,R0 ;取加數(shù)低字節(jié) ADDC A,R1 ;被加數(shù)低字節(jié)加A MOV R0,A DEC R0 DEC R1 DJNZ R7,NADDl INC R0 RET3 3利用堆棧利用堆棧 利用堆棧傳遞參數(shù)是在子程序嵌套中常采用的一種方法。在調(diào)用子程序前,用PUSH指令將子程序中所需數(shù)據(jù)壓入堆棧,進入執(zhí)行子程序時,再用POP指令從堆棧中彈出數(shù)據(jù)。例 編寫一個子程序,將R0和R1指向的內(nèi)部RAM中兩個3字節(jié)無符號整數(shù)相加,結(jié)果送到由R0指向的內(nèi)部RAM中。入口時
34、,R0和R1分別指向加數(shù)和被加數(shù)的低位字節(jié);出口時,R0指向結(jié)果的高位字節(jié)。低字節(jié)在高地址,高字節(jié)在低地址。 MAIN:MOV A,20H SWAP A PUSH ACC ;參數(shù)入棧 ACALL HEASC POP ACC MOV R0,A;存高位十六進制數(shù)轉(zhuǎn)換結(jié)果 INC R0 ;修改指針 PUSH 20H ;參數(shù)入棧 ACALL HEASC POP ACC MOV R0,A ;存低位十六進制數(shù)轉(zhuǎn)換結(jié)果 SJMP $ACCSPSPACCSPACC PC0-7 PC8-15調(diào)用前調(diào)用時返回主程序后R1HEASC:MOV R1,SP ;借用R1為堆棧指針 DEC R1 DEC R1 ;R1指向被
35、轉(zhuǎn)換數(shù)據(jù) XCH A,R1 ;取被轉(zhuǎn)換數(shù)據(jù) ANL A,#0FH ;取1位十六進制數(shù) ADD A,#2 ;偏移量調(diào)整,所加值為MOVC與DB間字節(jié)數(shù) MOVC A,A+PC ;查表 XCH A,R1 ;1B指令,存結(jié)果于堆棧 RET ;1B指令A(yù)SCTAB:DB 30H,31H,32H,33H,34H,35H,36H,37H DB 38H,39H,41H,42H,43H,44H,45H,46HSPACC PC0-7 PC8-15調(diào)用時R1w 例:碼制轉(zhuǎn)換2將內(nèi)部RAM20H單元中的十六進制數(shù)轉(zhuǎn)換為兩位ASCII碼,結(jié)果按高低順序存放在21H與22H單元。ORG0000HMAIN: MOVSP,
36、 #60H;設(shè)置堆棧初值MOVA, 20H;取被轉(zhuǎn)換的16進制數(shù)SWAPA;交換位置,以便對高位進行轉(zhuǎn)換PUSHACC;壓入堆棧ACALLHEXASC ;調(diào)用轉(zhuǎn)換子程序,對高位進行轉(zhuǎn)換POP 21H;從堆棧中取出轉(zhuǎn)換結(jié)果PUSH20H;將將原數(shù)據(jù)壓入堆棧ACALLHEXASC ;調(diào)用轉(zhuǎn)換子程序,對低位進行轉(zhuǎn)換POP 22H;從堆棧中取出轉(zhuǎn)換結(jié)果SJMP$;轉(zhuǎn)換結(jié)束,等待ORG0100HHEXASC:MOVR1, SP ;轉(zhuǎn)移堆棧指針,因SP不可修改DEC R1;下移指針,以便指向被轉(zhuǎn)換數(shù)據(jù)單元DEC R1MOVA, R1;從棧區(qū)中取出被轉(zhuǎn)換數(shù)據(jù)ANLA, #0FH;屏蔽高半字節(jié)ADDA,#02
37、H;修正查表指針MOVCA, A+PC;查ASCII表MOVR1, A;保存轉(zhuǎn)換結(jié)果到棧區(qū)RET;轉(zhuǎn)換子程序返回TAB:DB30H, 31H, 32H, 33H, 34H, 35H, 36H, 37HDB 38H, 39H, 41H, 42H, 43H, 44H, 45H, 46HEND4.5 4.5 常用程序舉例常用程序舉例一、一、 數(shù)制轉(zhuǎn)換數(shù)制轉(zhuǎn)換 單片機能識別和處理的是二進制碼,而輸入輸出設(shè)備(如LED顯示器、微型打印機等)則常使用ASC碼或BCD碼。為此,在單片機應(yīng)用系統(tǒng)中經(jīng)常需要通過程序進行二進制碼與BCD碼或ASC碼的相互轉(zhuǎn)換。 由于二進制數(shù)與十六進制數(shù)有直接的對應(yīng)關(guān)系,所以,為了
38、書寫和敘述的方便,一般將用十六進制數(shù)代替二進制數(shù)。例例 將一個字節(jié)二進制數(shù)轉(zhuǎn)換成將一個字節(jié)二進制數(shù)轉(zhuǎn)換成3 3位位非壓縮型非壓縮型BCD碼。碼。設(shè)一個字節(jié)二進制數(shù)在內(nèi)部RAM 40H單元, 轉(zhuǎn)換結(jié)果放入內(nèi)部RAM 50H, 51H, 52H單元中(高位在前)例如: 92H=146D 則其BCD碼為: 00000001 00000100 00000110 一個十進制數(shù)可表示為: Dn10n +Dn-110n-1 + + D0100 =(Dn10+Dn-1)10+Dn-2)10+)+D0當(dāng)n=3時, 上式可表示為: (D310+D2)10+D1)10+D0 例例 設(shè)設(shè)4位位BCD碼依次存放在內(nèi)存碼
39、依次存放在內(nèi)存 RAM中中 40H43H單元的單元的低低4 位位, 高高 4 位都為位都為0, 要求將其轉(zhuǎn)換為二進制數(shù)要求將其轉(zhuǎn)換為二進制數(shù), 結(jié)果存入結(jié)果存入 R2R3 中。中。 BCDHEX: MOV R0, 40H MOV R1, 03MOV R2, 0 MOV A, R0MOV R3, A LOOP: MOV A, R3MOV B, 10MUL ABMOV R3, A MOV A, BXCH A, R2MOVB, 10 MUL ABADD A, R2MOV R2, A INC R0 MOV A, R3ADD A, R0MOV R3, AMOV A, R2ADDC A, 0 MOV R2
40、, ADJNZ R1, LOOPRET 1. 加、加、 減法程序減法程序 例例4-18 將40H開始存放的 10 個字節(jié)的數(shù)與50H開始存放的10 個字節(jié)的數(shù)相減(假設(shè)被減數(shù)大于減數(shù))。 設(shè)被減數(shù)指針為 R0, 減數(shù)指針為 R1, 差數(shù)放回被減數(shù)單元, R5 存放字節(jié)個數(shù), 則程序如下: 二、二、 運算程序運算程序 SUB: MOV R0, 49HMOV R1, 59HMOV R5, 10CLR CSUB1: MOV A, R0SUBB A, R1MOV R0, ADEC R0DEC R1DJNZ R5, SUB1RET 例例4-194-19多字節(jié)多字節(jié)BCDBCD十進制數(shù)相加。十進制數(shù)相加。
41、 假設(shè)在內(nèi)部RAM的30H37H單元、38H3FH單元分別存放有兩個8字節(jié)BCD十進制數(shù),設(shè)計一段程序?qū)⑦@兩個數(shù)相加,并將結(jié)果存放到2FH37H單元中。數(shù)據(jù)存放模式是小地址存放數(shù)據(jù)的高字節(jié)。開始R208H(循環(huán)次數(shù))R037H(被加數(shù)首地址)R13FH(加數(shù)首地址)清除進位位Cy取被加數(shù)和加數(shù),兩數(shù)帶Cy相加調(diào)整地址指針R0+1、R1+1將Cy值存入2FH單元R2-1=0嗎?結(jié)束YNBCD碼調(diào)整,回存和值 ORG 0000H MOV R2,#08H ;設(shè)定循環(huán)次數(shù) MOV R0,#37H ;用R0做指針,指向被加數(shù)的低位字節(jié) MOV R1,#3FH ;用R1做指針,指向加數(shù)的低位字節(jié) CLR CLOOP:MOV A,R0 ;取被加數(shù) ADDC A,R1 DA A ;BC
溫馨提示
- 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)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年家紡布藝統(tǒng)一訂購協(xié)議模板
- 2024年規(guī)范格式員工解聘協(xié)議范本
- 2024年培訓(xùn)學(xué)校業(yè)務(wù)承接協(xié)議典范
- 2024年資格認(rèn)證代理掛靠服務(wù)協(xié)議
- 2024年簡化場地租賃協(xié)議范例
- 2024年水產(chǎn)養(yǎng)殖協(xié)議范本及條款詳解
- DB11∕T 1694-2019 生活垃圾收集運輸節(jié)能規(guī)范
- 2024年設(shè)備分期付款購銷協(xié)議典范
- 2024年房產(chǎn)租賃業(yè)務(wù)協(xié)議參考
- 2024年停車場租賃模板協(xié)議
- 突發(fā)事件應(yīng)急處理知識培訓(xùn)
- 糖尿病專科護士考試試題
- 錄音行業(yè)的就業(yè)生涯發(fā)展報告
- 人工智能概論-人工智能概述
- 鄉(xiāng)村旅游財務(wù)分析策劃方案
- 高校學(xué)生事務(wù)管理1
- (中職)ZZ030植物病蟲害防治賽項規(guī)程(7月19日更新)
- 2024年國能包神鐵路集團有限責(zé)任公司招聘筆試參考題庫附帶答案詳解
- 非甾體類抗炎藥課件
- 出入庫登記管理制度
- 內(nèi)科醫(yī)生的職業(yè)認(rèn)知和自我發(fā)展
評論
0/150
提交評論