匯編語言程序設(shè)計(jì)P228_第1頁
匯編語言程序設(shè)計(jì)P228_第2頁
匯編語言程序設(shè)計(jì)P228_第3頁
匯編語言程序設(shè)計(jì)P228_第4頁
匯編語言程序設(shè)計(jì)P228_第5頁
已閱讀5頁,還剩223頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、,第四章匯編語言程序設(shè)計(jì),4.1 概述,4.2 順序結(jié)構(gòu)程序,4.3 分支結(jié)構(gòu)程序,4.4 循環(huán)結(jié)構(gòu)程序,4.5 子程序結(jié)構(gòu),4.6 綜合程序舉例,4.7 本章小節(jié),4.8 思考與練習(xí)題,第四章匯編語言程序設(shè)計(jì),主要內(nèi)容:本章從程序結(jié)構(gòu)和實(shí)用角度出發(fā),通過典型的應(yīng)用實(shí)例介紹匯編語言程序的基本結(jié)構(gòu)及模塊化程序設(shè)計(jì),使學(xué)生進(jìn)一步理解和掌握51系列單片機(jī)的指令系統(tǒng),并掌握匯編語言程序設(shè)計(jì)的基本語言和技巧。 要求: 1、熟練運(yùn)用指令系統(tǒng),掌握循環(huán)程序、分支程序和搜索程序的設(shè)計(jì)方法; 2、熟練運(yùn)用指令系統(tǒng),掌握基本的運(yùn)算程序設(shè)計(jì)方法;,第四章匯編語言程序設(shè)計(jì),3、熟練運(yùn)用指令系統(tǒng),掌握數(shù)制和碼制轉(zhuǎn)換程序

2、的設(shè)計(jì)方法; 4、熟練掌握子程序結(jié)構(gòu),實(shí)現(xiàn)模塊化程序設(shè)計(jì); 5、深刻理解軟件、硬件的相互作用,不斷提高實(shí)際問題處理程序編寫能力。,4.1 概述,4.1 概述 程序設(shè)計(jì):為了解決某一個(gè)問題,將所設(shè)計(jì)應(yīng)用系統(tǒng)(單片機(jī)類型)的指令按一定順序組合在一起。即用計(jì)算機(jī)所能接受的語言把解決問題的步驟描述出來。 單片機(jī)匯編源程序結(jié)構(gòu)與通用微機(jī)匯編源程序結(jié)構(gòu)略有不同,原因是: 1、一般沒有可以直接利用的監(jiān)控程序,所有程序均要自己編寫。,4.1 概述,2、沒有像X86匯編語言程序那樣,可直接調(diào)用系統(tǒng)提供的中斷功能(如:BIOS中斷、DOS中斷)或Windows的API函數(shù)完成特定操作,即所有子程序(如鍵盤監(jiān)控子程

3、序、顯示驅(qū)動(dòng)程序、中斷服務(wù)程序等)均需要自己編寫。 匯編語言語句三種基本類型:指令語句、偽指令語句、宏指令語句。,4.1 概述,一、匯編語言偽指令 偽指令 匯編程序某些指令在匯編時(shí)并不產(chǎn)生目標(biāo)代碼,不影響程序的執(zhí)行,不是CPU能執(zhí)行的指令,只提供一些匯編控制信息的指令。 常用的偽指令: (1)設(shè)置起始地址ORG 格式:ORG nn 1、ORG:表明為后續(xù)源程序經(jīng)匯編后的目標(biāo)程序安排存放位置,nn則給出了存放的起始地址值;,4.1 概述,2、ORG總是出現(xiàn)在每段源程序或數(shù)據(jù)塊的開始; 3、在一個(gè)源程序中,可以多次使用ORG規(guī)定不同程序段的起始位置,但定義的地址順序應(yīng)從小到大,且不能重疊; 4、若

4、不用ORG,則匯編將從0000H單元開始存放目標(biāo)程序; 例4.1 ORG 3000H;表示后續(xù)的目標(biāo)程序代碼從3000H單元開始存放。MOV A,30H,4.1 概述,(2)定義字節(jié)DB 格式:標(biāo)號(hào):DB字節(jié)數(shù)據(jù)項(xiàng)表 1、標(biāo)號(hào)區(qū)段可有可無,項(xiàng)表指中間用逗號(hào)分開的字節(jié)、數(shù)、字符串或用引號(hào)括起來的ASC碼字符串(一個(gè)字符用ASC碼表示,就相當(dāng)于一個(gè)字節(jié))。 2、功能:把項(xiàng)表的數(shù)據(jù)存入從標(biāo)號(hào)開始的連續(xù)單元中。 例4.2 ORG 2000HSEG1:DB 35H,78H,4.1 概述,SEG2:DB DAY END 則 (2000H)=35H,(2001H)=78H,(2002H)=44H,(2003

5、H)=41H,(2004H)=59H 注意:項(xiàng)表中若為數(shù)值,其取值范圍應(yīng)為00HFFH,若為字符串,其長度應(yīng)限制在80個(gè)字符內(nèi)。 (3)定義字DW 格式:標(biāo)號(hào):DW字節(jié)數(shù)據(jù)項(xiàng)表 DW的基本含義與DB相同,不同的是DW定義16位數(shù)據(jù),常用來建立地址表。存放時(shí)一個(gè)字需兩個(gè)單元,高8位先存放,低8位后存放。,4.1 概述,例4.3 ORG 8000HHETAB:DW 7234H,8AH,10 匯編后:(8000H)=72H,(8001H)=34H,(8002H)=00H,(8003H)=8AH,(8004H)=00H,(8005H)=0AH (4)數(shù)據(jù)地址賦值DATA 格式為: 字符名稱 DATA

6、數(shù)據(jù)或表達(dá)式 把數(shù)據(jù)地址或代碼地址賦予字符名稱。常用于定義數(shù)據(jù)地址,它可以先使用后定義(因?yàn)镈ATA定義的字符名稱作為標(biāo)號(hào)登記在符號(hào)表中,而EQU沒定義),這點(diǎn)與EQU不同。表達(dá)式應(yīng)是可求值的。,4.1 概述,例4.4ORG8000H INDEXJDATA 8096H LJMP INDEXJ END 等價(jià)于ORG8000H LJMP 8096H END,4.1 概述,(5)賦值(等值)EQU 格式:標(biāo)號(hào) EQU 項(xiàng)或表達(dá)式 功能:將語句操作數(shù)的值賦于本語句的標(biāo)號(hào),用EQU賦過值的標(biāo)號(hào)名可以用作數(shù)據(jù)地址、代碼地址、位地址或是一個(gè)立即數(shù),它可以是8位、也可以是16位。 注意: 1、在同一程序中,用

7、EQU偽指令對(duì)標(biāo)號(hào)賦值后,該標(biāo)號(hào)的值在整個(gè)程序中不能再改變; 2、用EQU定義的字符須先定義后使用。,4.1 概述,例4.5 ORG8000H AAEQUR6;AA與R6等值MOV A,AA ;(R6)的值送入A中 (6)位地址符號(hào)命令BIT 格式: 字符名稱 BIT 位地址 功能:給一個(gè)可位尋址的位單元起一個(gè)名字。用BIT定義過的位單元可用名字使用。 注意:名字必須是以字母開頭的字母數(shù)字串,它必須是事先未定義過的。,4.1 概述,例4.6 A1BITP1.0A2BIT02H (7)源程序結(jié)束END 格式:標(biāo)號(hào):END 表達(dá)式 1、標(biāo)號(hào)和表達(dá)式是可有可無的。 2、END是一個(gè)結(jié)束標(biāo)志,在一個(gè)程

8、序中只允許出現(xiàn)一個(gè)END語句,而且它必須放在整個(gè)程序的最后面。 (8)定義存儲(chǔ)空間DS 格式: 標(biāo)號(hào):DS 表達(dá)式 1、由標(biāo)號(hào)指定單元開始,定義一個(gè)存儲(chǔ)區(qū),以備源程序使用。,4.1 概述,2、存儲(chǔ)區(qū)內(nèi)預(yù)留的存儲(chǔ)單元數(shù)由數(shù)據(jù)或字符表達(dá)式的值決定。 例4.7 ORG 8000HTEMP:DS 08HDB 30H,8AH 即8000H8007H單元保留備用,(8008H)=30H,(8009H)=8AH。 二、匯編語言程序設(shè)計(jì)的基本步驟 1、分析問題(調(diào)研),確定方案和計(jì)算方法 目的:對(duì)需要解決的問題進(jìn)行分析,以求對(duì)問題有正確的理解。,4.1 概述,2、了解應(yīng)用系統(tǒng)的硬件配置、性能指標(biāo)。 3、建立系

9、統(tǒng)數(shù)學(xué)模型,確定控制算法和操作步驟。 4、編制說明要解決問題的程序框圖。 畫程序框圖:用各種圖形、符號(hào)、指向線等來說明程序設(shè)計(jì)的過程。框圖步驟寫得越細(xì)致,編程時(shí)也就越方便。 目的:把具有一定功能的各個(gè)部分有機(jī)地聯(lián)系起來,可以使人們抓住程序的基本線索,對(duì)全局有完整的了解。,4.1 概述,好處: (1)容易發(fā)現(xiàn)設(shè)計(jì)思想上的錯(cuò)誤和矛盾,便于找出解決問題的途徑。 (2)便于把較大的程序分成若干個(gè)模塊,從而分頭進(jìn)行設(shè)計(jì),最后合在一起聯(lián)調(diào)。 5、按所使用計(jì)算機(jī)的指令系統(tǒng),依據(jù)框圖寫出匯編語言程序。 編程的三個(gè)原則:盡可能的節(jié)省數(shù)據(jù)存儲(chǔ)單元;縮短程序長度;減少執(zhí)行時(shí)間。,4.1 概述,.合理分配存儲(chǔ)器單元和

10、了解I/O接口地址。 .按功能設(shè)計(jì)程序,明確各程序之間的相互關(guān)系。 .用注釋行說明程序,便于閱讀、調(diào)試和修改。 6、上機(jī)調(diào)試程序,直至完成預(yù)定功能。 MCS-51 程序總體組成 MCS-51匯編語言源程序一般由程序頭、主程序、完成特定操作的子程序(可能不止一個(gè))及相應(yīng)功能的中斷服務(wù)程序等部分組成。 結(jié)構(gòu)如下:,4.1 概述,- 程序頭( 即定義變量和等值符號(hào))- SCL BIT P1.2 ;定義SCL位變量SDA BIT P1.3 ;定義SDA位變量ByteCon DATA 30H ;定義字節(jié)變量ByteCon ORG nnnn ;CPU復(fù)位后,第一指令機(jī)器碼存放單元地址,具體值由CPU類型決

11、定。 例4.8 在51系列中,復(fù)位后PC=0000,因此在51系列中,第一條指令存放在ROM的0000H單元中,即nnnn為“0000H”。,4.1 概述,LJMP Main ;一般第一條指令是跳轉(zhuǎn)指令,跳到主程序入口地址,其中“Main”是主程序入口地址標(biāo)號(hào)。 主程序不能直接存放在復(fù)位后PC指向的存儲(chǔ)單元,原因是這一區(qū)域往往是中斷服務(wù)程序的入口地址,不能覆蓋,否則不能使用相應(yīng)的中斷功能。 例4.9 在51系列中,外部中斷0的入口地址為 0003H,顯然只有0000H、0001H和0002H三個(gè)單元,剛好可以存放一條長跳轉(zhuǎn)指令的機(jī)器碼。,4.1 概述,- 主程序 - ORG yyyy ;其中y

12、yyy就是主程序代碼存放區(qū)的首地址,如0100H Main: MOV SP,#5FH ;初始化有關(guān)寄存器,如設(shè)置SP、選擇工作寄存器組。 ;初始化中斷控制寄存器等 ;主程序?qū)嶓w,具體指令由程序功能決定 LCALL SUB1 ;調(diào)用子程序1 ,其中SUB1為子程序名 ; END,4.1 概述,- 子程序結(jié)構(gòu) - ORG zzzz ;其中zzzz就是子程序代碼存放區(qū)的首地址,可以不用ORG指令,直接將子程序存放主程序后。 SUB1:PUSH PSW PUSH Acc;通過PUSH指令保護(hù)子程序中用到的有關(guān)寄存器,如Acc、PSW 等,即保護(hù)現(xiàn)場 ;子程序?qū)嶓w,具體指令由程序功能決定 POP Acc

13、 POP PSW ;恢復(fù)現(xiàn)場 RET ;子程序最后一條指令,使子程序指令運(yùn)行結(jié)束后,返回主程序斷點(diǎn)。,4.1 概述,- 中斷服務(wù)程序結(jié)構(gòu) - ORG kkkk ;其中kkkk就是中斷程序代碼存放區(qū)的首地址 PUSH PSW PUSH Acc ;通過PUSH指令保護(hù)中斷服務(wù)程序中用到的有關(guān)寄存器,如 Acc、PSW等,即保護(hù)現(xiàn)場 ;中斷服務(wù)程序?qū)嶓w,具體指令由程序功能決定 POP Acc POP PSW ;恢復(fù)現(xiàn)場,4.1 概述,CLR TI ;清除中斷標(biāo)志(在51系列中,對(duì)于電平觸發(fā)的外中斷INT0和 INT1、串行接收及發(fā)送中斷 RI、TI等,不自動(dòng)清除,需要在中斷服務(wù)結(jié)束前,通過CLR指令

14、清除。 RETI ;中斷服務(wù)程序最后一條指令,返回主程序斷點(diǎn)。 為了確保子程序、中斷服務(wù)程序運(yùn)行結(jié)束后,能夠正確返回,從斷點(diǎn)處繼續(xù)執(zhí)行主程序,必須注意在子程序以及中斷服務(wù)程序中堆棧操作指令的匹配問題,否則將無法返回。,4.1 概述,例4.10 在上述子程序結(jié)構(gòu)中,假設(shè)SUB1子程序入口地址為2000H,即主程序內(nèi)“LCALL SUB1”指令等效于“LCALL 2000”。假設(shè)該指令機(jī)器碼首地址為1000H,且指令執(zhí)行前,SP=5FH,則“LCALL 2000” 指令執(zhí)行過程中PC和SP內(nèi)容如下: (1) PCPC+3 ,即PC=1003H( 即斷點(diǎn)地址 ); (2) SPSP+1,即SP=60

15、H,并把PC低8位壓入堆棧,于是(60H)=03; (3) SPSP+1,即SP=61H,并把PC高8位壓入堆 棧,于是(61H)=10;,4.1 概述,(4) 把 SUB1入口地址裝入PC,即 PC=2000H。 可見,“LCALL 2000”指令執(zhí)行后,PC=2000H,已指向子程序SUB1第一條指令所在的存儲(chǔ)單元地址;SP=61H。 在子程序中 PUSH Acc ;執(zhí)行后,SP=62H,(62H)就是Acc的當(dāng)前值,假設(shè)為XX PUSH PSW ;執(zhí)行后,SP=63H,(63H)就是PSW的當(dāng) 前值,假設(shè)為YY 返回前 POP PSW ;執(zhí)行后,PSW(SP),即將(63H)單元,4.1

16、 概述,中原來的PSW返回給PSW;SPSP1,即SP=62H POP Acc ;執(zhí)行后,ACC(SP),即將(62H)單元中原來的Acc返回給Acc ;SPSP1,即SP=61H RET ;執(zhí)行后,PC高8位(SP),即將(61H)單元內(nèi)容10H傳給PC高8位,SPSP1,即SP=60H;PC低8位(SP),即將(60H)單元內(nèi)容03H傳給PC;低8位,SPSP1,即SP=5FH 結(jié)果PC=1003H(重新裝入主程序斷點(diǎn)地址),4.1 概述,匯編語言程序按其結(jié)構(gòu)可分為以下四類: (1)順序結(jié)構(gòu); (2)分支結(jié)構(gòu); (3)循環(huán)結(jié)構(gòu); (4)子程序結(jié)構(gòu)。,4.2 順序結(jié)構(gòu)程序,4.2 順序結(jié)構(gòu)程

17、序 最簡單的一種結(jié)構(gòu),又稱簡單程序。 特點(diǎn): 按照程序編寫的順序依次執(zhí)行,不發(fā)生任何分支 或轉(zhuǎn)移。(程序走向只有一條路徑。) 例4.11 將兩個(gè)半字節(jié)數(shù)組合成一個(gè)字節(jié)數(shù)。 設(shè)內(nèi)部RAM中40H、41H單元分別存放著8位二進(jìn)制數(shù),要求將兩個(gè)單元中的低半字節(jié)合并成一個(gè)字節(jié)后,存入42H單元。40H的低4位作為42H的高4位。,4.2 順序結(jié)構(gòu)程序,分析: 首先要取數(shù)送A(傳送指令),分離出低4位(邏輯與0FH),用A半字節(jié)交換送到高4位,地址加1,取另一個(gè)數(shù)低4位數(shù)(邏輯與0FH),用或合成一個(gè)字節(jié)。 解: START:MOV R1,#40H MOV A,R1 ANL A,#0FH ;取第一個(gè)半字

18、節(jié) SWAP A ;移至高4位,4.2 順序結(jié)構(gòu)程序,INC R1XCH A,R1;取第二個(gè)字節(jié)ANL A,#0FH ;取第二個(gè)半字節(jié)ORL A,R1;拼字INC R1MOV R1,A ;存放結(jié)果RET 例4.12 將20H單元的兩個(gè)BCD碼拆開并變成ASC碼,存入21H、22H單元。注意:ASC碼09為30H39H。 分析:,4.2 順序結(jié)構(gòu)程序,把BCD數(shù)除以10,商A余B,剛好把兩個(gè)BCD碼分別移到A、B的低4位,然后再各自與30H相“或”,即變成ASC碼。其程序框圖如圖4-1所示。 采用先把20H中低4位BCD碼交換出來加以轉(zhuǎn)換、存放,然后再把高4位BCD碼交換至低4位加以轉(zhuǎn)換、存放。

19、其程序框圖如圖4-2所示。,4.2 順序結(jié)構(gòu)程序,圖4-1 BCD碼轉(zhuǎn)換為ASCII碼方法一流程圖解,4.2 順序結(jié)構(gòu)程序,編程: ORG 2000HMOV A,20HMOV B,#0AH ;用0AH作除數(shù)DIV ABORL B,#30H ;低4位BCD碼變成ASC碼MOV 22H,B ORL A,#30H ;高4位BCD碼變成ASC碼 MOV 21H,AEND,4.2 順序結(jié)構(gòu)程序,圖4-2 BCD碼轉(zhuǎn)換為ASCII碼方法二流程圖解,4.2 順序結(jié)構(gòu)程序,編程: ORG 2000HMOV R0,#22HMOV R0,#00H MOV A,20HXCHD A,R0 ORL 22H,#30H S

20、WAP AORL A,#30HMOV 21H,AEND,4.3 分支結(jié)構(gòu)程序,4.3 分支結(jié)構(gòu)程序 一、分支程序設(shè)計(jì)綜述 分支結(jié)構(gòu)程序:根據(jù)程序要求無條件或有條件改變程序執(zhí)行的順序,選擇程序的流向。 特點(diǎn):程序中含有轉(zhuǎn)移類指令。 關(guān)鍵:正確選用轉(zhuǎn)移指令。 單重分支程序:一個(gè)判斷決策框,程序有兩條出路。,4.3 分支結(jié)構(gòu)程序,兩種分支結(jié)構(gòu),4.3 分支結(jié)構(gòu)程序,轉(zhuǎn)移指令有3種: 1、無條件轉(zhuǎn)移 程序轉(zhuǎn)移方向是設(shè)計(jì)者事先安排的,與已執(zhí)行程序的結(jié)果無關(guān),使用時(shí)只需給出正確的轉(zhuǎn)移目標(biāo)地址或偏移量即可。(LJMP、AJMP 、SJMP) 2、條件轉(zhuǎn)移 根據(jù)已執(zhí)行程序?qū)?biāo)志位或A或?qū)?nèi)部RAM某位的影響結(jié)

21、果,決定程序的走向,形成各種分支。(JZ/JNZ、CJNE、DJNZ、位控制轉(zhuǎn)移類指令) 在編寫有條件轉(zhuǎn)移語句時(shí)要特別注意以下兩點(diǎn): (1)在使用條件轉(zhuǎn)移指令形成分支前,一定要安排可供條件轉(zhuǎn)移指令進(jìn)行判別的條件。,4.3 分支結(jié)構(gòu)程序,例如,若采用“JC rel”指令,在執(zhí)行此指令前必須使用影響Cy標(biāo)志的指令;若采用“CJNE A,#data,rel”指令,在執(zhí)行此指令前必須使用改變A內(nèi)容的指令,以便為測(cè)試做準(zhǔn)備。 (2)要正確選定所用的轉(zhuǎn)移條件和轉(zhuǎn)移目標(biāo)地址。 3、散轉(zhuǎn)(JMPA+DPTR ) 它是根據(jù)某種已輸入的“或”運(yùn)算的結(jié)果,使程序轉(zhuǎn)向各個(gè)處理程序中去。 操作:把16位DPTR的內(nèi)容與

22、“或”運(yùn)算的結(jié)果與在A中的8位無符號(hào)數(shù)相加,形成地址,裝入PC,即散轉(zhuǎn)的目的地址。其操作結(jié)果不影響A和DPTR。(JMP),4.3 分支結(jié)構(gòu)程序,二、無條件/條件轉(zhuǎn)移程序 分支程序中最常見的一類。其中,條件轉(zhuǎn)移類程序編寫較容易出錯(cuò),編寫時(shí)需要確定轉(zhuǎn)移條件。 例4.13 兩個(gè)無符號(hào)數(shù)比較大小。同P59頁例4-7 解 設(shè)外部RAM存儲(chǔ)單元ST1和ST2中存放兩個(gè)不帶符號(hào)的二進(jìn)制數(shù),找出其中的大數(shù)存入ST3單元中。,4.3 分支結(jié)構(gòu)程序,圖4-3 兩個(gè)無符號(hào)數(shù)比較大小程序框圖,4.3 分支結(jié)構(gòu)程序,解: ORG 8000H ST1 EQU 8040H START:CLR C ;進(jìn)位位清0 MOV D

23、PTR,#ST1 ;讀數(shù)據(jù)指針 MOVX A,DPTR ;取第一個(gè)數(shù) MOV R2,A ;暫存R2 INC DPTR MOVX A,DPTR ;取第二個(gè)數(shù) SUBB A,R2 ;兩數(shù)比較 JNC BIG1 ;若Cy=0,則轉(zhuǎn)BIG1(第二個(gè)數(shù)大),4.3 分支結(jié)構(gòu)程序,XCH A,R2 ;第一個(gè)數(shù)大 BIG0:INC DPTR MOVX DPTR,A ;存大數(shù) RET BIG1:MOVX A,DPTR ;第二個(gè)數(shù)大 SJMP BIG0 END 上面程序中,應(yīng)用帶借位的減法指令SUBB比較兩數(shù)的大小。在執(zhí)行指令前,應(yīng)先把進(jìn)位位清“0”。執(zhí)行JNC指令后形成分支,指令中BIG1為標(biāo)號(hào)地址,表示相對(duì)

24、偏移量rel。,4.3 分支結(jié)構(gòu)程序,例4.14 設(shè)5AH單元中有一變量X,請(qǐng)編寫計(jì)算下列函數(shù)式的程序,結(jié)果存入5BH單元。 同P61頁例4-8.,4.3 分支結(jié)構(gòu)程序,圖4-4 例4.6程序流程圖,4.3 分支結(jié)構(gòu)程序,解:根據(jù)題意首先計(jì)算X2(使用乘法)并暫存于R1中,因?yàn)閄2最大值為225,可只用一個(gè)寄存器,然后根據(jù)X值的范圍,決定Y的值。R0作中間寄存器。 編程: ORG 2000H MOV A,5AH MOV B,A MUL AB ;AX2 MOV R1,A MOV A,5AH ;重新把X裝入A CJNE A,#10,L1,4.3 分支結(jié)構(gòu)程序,L1:JC L2 ;C=1,X10轉(zhuǎn)L

25、2 MOV R0,#41 ;先假設(shè)X15 CJNE A,#10H,L3 ;與16比較 L3:JNC L4 ; C=0,X15轉(zhuǎn)L4 MOV A,R1 ADD A,#8 ;10X15,Y=X2+8 MOV R0,A SJMP L4 L2:MOV A,R1CLR C SUBB A,#01 ;X10,Y=X2-1,4.3 分支結(jié)構(gòu)程序,MOV R0,A L4:MOV 5BH,R0 ;存結(jié)果 SJMP $ END 由于本題的具體情況,在判別(A)10和(A)15時(shí)采用的是“CJNE”和“JC”以及“CJNE”和“JNC”兩條指令相結(jié)合的方法。 條件分支程序與簡單程序的區(qū)別在于:分支程序存在兩個(gè)或兩個(gè)以

26、上的結(jié)果。要根據(jù)給定的條件進(jìn)行判斷,以得到某一個(gè)結(jié)果。這樣,就要用到比較命令、測(cè)試指令以及無條件/條件轉(zhuǎn)移指令。條件分支程序設(shè)計(jì) 的技巧,就在于正確而巧妙地使用這些命令。,4.3 分支結(jié)構(gòu)程序,例題:求符號(hào)函數(shù)的值。已知片內(nèi)RAM的40H單元內(nèi)有一自變量X,編制程序按如下條件求函數(shù)Y的值,并將其存入片內(nèi)RAM的41H單元中。 1 X0 Y= 0 X=0 -1X0,解:此題有三個(gè)條件,所以有三個(gè)分支程序。這是一個(gè)三分支歸一的條件轉(zhuǎn)移問題。 X是有符號(hào)數(shù),判斷符號(hào)位是0還是1可利用JB或JNB指令。判斷X是否等于0則直接可以使用A的判0指令。 程序流程圖如右圖所示。,ORG 1000H START

27、: MOV A, 40H ; 將X送入A中 JZ COMP ; 若A為0,轉(zhuǎn)至COMP處 JNB ACC.7, POST ; 若A第7位不為1(X為正數(shù)),則程序轉(zhuǎn)到POST處,否則(X為負(fù)數(shù))程序往下執(zhí)行 MOV A, #0FFH ; 將1(補(bǔ)碼)送入A中 SJMP COMP ; 程序轉(zhuǎn)到COMP處 POST: MOV A, #01H ; 將+1送入A中 COMP: MOV 41H, A ; 結(jié)果存入Y SJMP $ ; 程序執(zhí)行完,“原地踏步” END,4.3 分支結(jié)構(gòu)程序,三、散轉(zhuǎn)程序設(shè)計(jì) 散轉(zhuǎn)程序:一種并行分支程序(多分支程序),它是根據(jù)某種輸入或運(yùn)算結(jié)果,分別轉(zhuǎn)向各個(gè)處理程序。轉(zhuǎn)移的

28、地址最多為256個(gè)。其結(jié)構(gòu)如圖下所示。,4.3 分支結(jié)構(gòu)程序,散轉(zhuǎn)程序設(shè)計(jì)采用下面兩種方法:(JMP ADPTR) (1)DPTR固定,根據(jù)A的內(nèi)容,程序轉(zhuǎn)入相應(yīng)的分支程序中去。(2)A清“0”,根據(jù)DPTR的值,決定程序轉(zhuǎn)向目的地址。DPTR的值可用查表或其他方法獲得。 1、采用轉(zhuǎn)移指令表 在許多應(yīng)用中,需要根據(jù)某標(biāo)志單元的內(nèi)容(輸入 或運(yùn)算結(jié)果)0,1,2,n,分別轉(zhuǎn)向操作程序0、操作程序1、操作程序2、操作程序n。,4.3 分支結(jié)構(gòu)程序,解決步驟: (1)可先用“AJMP”或“LJMP”指令按序組成一個(gè)轉(zhuǎn)移表; (2)將轉(zhuǎn)移表首地址裝入DPTR中; (3)將標(biāo)志單元的內(nèi)容裝入A經(jīng)運(yùn)算后作

29、為變址值; (4)執(zhí)行“JMP ADPTR”指令實(shí)現(xiàn)散轉(zhuǎn)。 例4.15 128種分支轉(zhuǎn)移程序。根據(jù)入口條件轉(zhuǎn)移到128個(gè)目的地址。,4.3 分支結(jié)構(gòu)程序,圖4-5 分支轉(zhuǎn)移程序框圖,4.3 分支結(jié)構(gòu)程序,解: 入口:(R3)=轉(zhuǎn)移目的地址的序號(hào)00H7FH。出口:轉(zhuǎn)移到相對(duì)子程序入口。 編程: JMP-128:MOV A,R3 CLR C RLC A ;A(A)2 MOV DPTR,#JMPTAB JMP A+DPTR JMPTAB:AJMP ROUT00 ;128個(gè)子程序首址 AJMP ROUT7F,4.3 分支結(jié)構(gòu)程序,此程序要求128個(gè)轉(zhuǎn)移目的地址(ROUT00ROUT7F)必須駐留在與

30、絕對(duì)轉(zhuǎn)移指令A(yù)JMP同一個(gè)2KB存儲(chǔ)區(qū)內(nèi)。RL指令對(duì)變址部分乘以2,是由于每條AJMP指令占用2個(gè)字節(jié)。,4.3 分支結(jié)構(gòu)程序,2、采用地址偏移量表 上面介紹的散轉(zhuǎn)程序,首先必須建立轉(zhuǎn)移指令表,程序根據(jù)散轉(zhuǎn)點(diǎn)執(zhí)行“JMP ADPTR”指令,進(jìn)入轉(zhuǎn)移表后,再由雙字節(jié)“AJMP”指令轉(zhuǎn)入2KB空間范圍內(nèi)的操作入口或由三字節(jié)“LJMP” 指令轉(zhuǎn)入64KB空間范圍內(nèi)的操作入口。 如果散轉(zhuǎn)點(diǎn)較少,所有操作程序處在同一頁(256B)時(shí),可使用地址偏移量轉(zhuǎn)移表。 例4.17 根據(jù)R7的內(nèi)容轉(zhuǎn)向5個(gè)操作程序。 解: JUMP3:MOV A,R7 MOV DPTR,#TAB3 MOVC A,A+DPTR,4.3

31、 分支結(jié)構(gòu)程序,JMP A+DPTR TAB3: DB OPR0-TAB3 DB OPR1-TAB3 DB OPR2-TAB3 DB OPR3-TAB3 DB OPR4-TAB3 OPR0:操作程序0 OPR1:操作程序1 OPR2:操作程序2 OPR3:操作程序3 OPR4:操作程序4,4.3 分支結(jié)構(gòu)程序,從本例可以看出,地址偏移量表每項(xiàng)對(duì)應(yīng)一個(gè)操作程序的入口,占一個(gè)字節(jié),分別表示對(duì)應(yīng)入口地址與表首的偏移量。 使用這種方法,地址偏移量表的長度加上各操作程序長度必須在同一頁內(nèi)。當(dāng)然,最后一個(gè)操作程序的長度不受限制,只要其程序入口與地址偏移量表首的偏移量在一個(gè)字節(jié)內(nèi)(小于256)就可以。,4.

32、3 分支結(jié)構(gòu)程序,3、采用轉(zhuǎn)向地址表 采用地址偏移量表的方法,其轉(zhuǎn)向范圍局限于一頁,使用受限制。若使用轉(zhuǎn)向較大的范圍,方法: (1)建立一個(gè)轉(zhuǎn)向地址表,即將所要轉(zhuǎn)向的雙字節(jié)地址組成一個(gè)表; (2)在散轉(zhuǎn)時(shí),先用查表方法獲得表中的轉(zhuǎn)向地址; (3)將該地址裝入DPTR中,再清A; (4)執(zhí)行“JMP ADPTR”指令,程序轉(zhuǎn)入所要到達(dá)的目的地址中去。 例4.18 根據(jù)R7的內(nèi)容轉(zhuǎn)入各對(duì)應(yīng)的操作程序中去。 解 設(shè)轉(zhuǎn)移入口地址為OPR0、OPR1、OPRn ,散轉(zhuǎn)程序及轉(zhuǎn)移表如下:,4.3 分支結(jié)構(gòu)程序,JMUP4:MOV DPTR,#TAB4 MOV A,R7 ADD A,R7 ;A(R7)2 J

33、NC NADD INC DPH ;(R7)2進(jìn)位加至DPH NADD:MOV R3,A ;暫存 MOVC A,ADPTR ;取地址高8位 XCH A,R3 ;置轉(zhuǎn)移地址高8位 INC A MOVC A,ADPTR ;取地址低8位,4.3 分支結(jié)構(gòu)程序,MOV DPL,A ;置轉(zhuǎn)移地址低8位 MOV DPH,R3 CLR A JMP ADPTR TAB4:DW OPR0 DW OPR1 DW OPRn 這種散轉(zhuǎn)方法可以達(dá)到64KB地址范圍內(nèi)的轉(zhuǎn)移,但也可看出,散轉(zhuǎn)數(shù)n小于256。若要使n大于255,可用雙字節(jié)加法運(yùn)算的方法修改DPTR。,4.4 循環(huán)結(jié)構(gòu)程序,4.4 循環(huán)結(jié)構(gòu)程序 循環(huán)程序設(shè)計(jì):

34、能連續(xù)多次重復(fù)執(zhí)行的某段程序。 目的:縮短程序長度,節(jié)省存儲(chǔ)單元,提高所編寫程序的質(zhì)量。 一、循環(huán)結(jié)構(gòu)程序組成 (1)初始化部分 為循環(huán)程序作準(zhǔn)備。如設(shè)置循環(huán)次數(shù)計(jì)數(shù)器初值,地址指針置初值,為其他變量賦初值等。一個(gè)重要部分,不注意容易出錯(cuò)。 (2)處理部分 重復(fù)執(zhí)行的程序段,循環(huán)程序的實(shí)體。,4.4 循環(huán)結(jié)構(gòu)程序,(3)循環(huán)控制部分 每執(zhí)行一次循環(huán)體后,都要為下一次循環(huán)作必要的準(zhǔn)備。如修改計(jì)數(shù)器值;檢查循環(huán)條件是否符合,以決定繼續(xù)循環(huán)或退出循環(huán)。 (4)結(jié)束部分 分析或存放執(zhí)行結(jié)果。 二、循環(huán)結(jié)構(gòu)程序兩種基本結(jié)構(gòu) (1)計(jì)數(shù)循環(huán)結(jié)構(gòu)(先處理后控制): 先進(jìn)入處理部分再控制循環(huán)。此結(jié)構(gòu)至少執(zhí)行一

35、次循環(huán)體;,4.4 循環(huán)結(jié)構(gòu)程序,(2)條件循環(huán)結(jié)構(gòu)(先控制后處理): 先控制循環(huán),后進(jìn)入處理部分。此結(jié)構(gòu)有時(shí)不進(jìn)入循環(huán)體就退出循環(huán),故稱之“允許0次循環(huán)的循環(huán)程序”。 注:循環(huán)結(jié)構(gòu)的程序,其關(guān)鍵是控制循環(huán)次數(shù)。 對(duì)循環(huán)次數(shù)的控制方法有: 循環(huán)次數(shù)已知,用計(jì)數(shù)器控制循環(huán); 次數(shù)未知,按條件控制循環(huán); 按邏輯尺控制循環(huán)。 有些情況下,循環(huán)體中的處理部分為分支程序,這就構(gòu)成分支循環(huán)結(jié)構(gòu)。實(shí)際中常用邏輯尺來控制分支和循環(huán)。所謂邏輯尺就是一個(gè)存儲(chǔ)單元(字節(jié)或字單元),在這存儲(chǔ)單元中的每一位便是一個(gè)標(biāo)志,它有兩個(gè)狀態(tài)0或1。根據(jù)標(biāo)志位為0或?yàn)?就可以實(shí)現(xiàn)兩路分支,多個(gè)標(biāo)志就可重復(fù)地實(shí)現(xiàn)分支。可見,重復(fù)的

36、次數(shù)就是邏輯尺中設(shè)定的位數(shù)。,4.4 循環(huán)結(jié)構(gòu)程序,4.4 循環(huán)結(jié)構(gòu)程序,三、循環(huán)程序分類 單循環(huán)程序: 結(jié)構(gòu)特點(diǎn):循環(huán)體為順序結(jié)構(gòu)或分支結(jié)構(gòu),每循環(huán)一次,執(zhí)行一次循環(huán)體程序。循環(huán)體中不包含循環(huán)程序。 51所用指令: DJNZ Rn,rel;以Rn作控制計(jì)數(shù)器 DJNZ direct,rel;以direct作控制計(jì)數(shù)器 多重循環(huán)程序(循環(huán)嵌套) 結(jié)構(gòu)特點(diǎn):在循環(huán)體中還包含有循環(huán)的程序。若把每重循環(huán)的內(nèi)部看作一個(gè)整體,則多重循環(huán)結(jié)構(gòu)與單循環(huán)結(jié)構(gòu)是一樣的。,4.4 循環(huán)結(jié)構(gòu)程序,四、使用多重循環(huán)程序必須注意的問題 循環(huán)嵌套必須層次分明,不允許產(chǎn)生內(nèi)外層交叉;外循環(huán)可以一層層向內(nèi)循環(huán)進(jìn)入,結(jié)束時(shí)由里

37、向外一層層退出;內(nèi)循環(huán)體可以直接轉(zhuǎn)入外循環(huán)體,實(shí)現(xiàn)一個(gè)循環(huán)由多個(gè)條件控制的循環(huán)結(jié)構(gòu)方式。,4.4 循環(huán)結(jié)構(gòu)程序,五、舉例 例4.11 多個(gè)單字節(jié)數(shù)據(jù)求和。 解 設(shè)Xi為單字節(jié)數(shù)(i=1n),依次存放在內(nèi)部RAM中50H單元開始的連續(xù)單元中。 要求n放入R2中,把計(jì)算結(jié)果存入R3R4中(高位存入R3,低位存入R4)。,4.4 循環(huán)結(jié)構(gòu)程序,圖4-6 多個(gè)單字節(jié)數(shù)據(jù)求和程序框圖,4.4 循環(huán)結(jié)構(gòu)程序,參考程序 ADD1:MOV R3,#00H MOV R4,#00H MOV R2,#n ;R2為循環(huán)次數(shù)計(jì)數(shù)器 MOV R0,#50H ;R0作間址寄存器用它來尋址Xi LOOP:MOV A,R4 ;

38、取部分和低位 ADD A,R0 ;與Xi相加 MOV R4,A INC R0 ;地址加1 CLR A ADDC A,R3 ;低位字節(jié)向高位進(jìn)位 MOV R3,A DJNZ R2,LOOP ;未加完繼續(xù)重復(fù),練習(xí)題,例題 已知片內(nèi)RAM 30H3FH單元中存放了16個(gè)二進(jìn)制無符號(hào)數(shù),編制程序求它們的累加和,并將其和數(shù)存放在R4, R5中。,解:每次求和的過程相同,可以用循環(huán)程序?qū)崿F(xiàn)。16個(gè)二進(jìn)制無符號(hào)數(shù)求和,循環(huán)程序的循環(huán)次數(shù)應(yīng)為16次(存放在R2中),它們的和放在R4, R5中(R4存高8位,R5存低8位)。程序流程圖如右圖所示。,程序如下: ORG 1000H START: MOV R0,

39、#30H MOV R2, #10H; 設(shè)置循環(huán)次數(shù)(16) MOV R4, #00H; 和高位單元R4清0 MOV R5, #00H; 和低位單元R5清0 LOOP: MOV A, R5; 和低8位的內(nèi)容送A ADD A, R0; 將R0與R5的內(nèi)容相加并產(chǎn)生進(jìn)位Cy MOV R5, A; 低8位的結(jié)果送R5 CLR A; A清0 ADDC A, R4; 將R4的內(nèi)容和Cy相加 MOV R4, A; 高8位的結(jié)果送R4 INC R0; 地址遞增(加1) DJNZ R2, LOOP;若循環(huán)次數(shù)減1不為0,則轉(zhuǎn)到 LOOP處循環(huán);否則,循環(huán)結(jié)束 SJMP $ END,例題 編制程序?qū)⑵瑑?nèi)RAM的3

40、0H4FH單元中的內(nèi)容傳送至片外RAM的2000H開始的單元中。 同書上P48,P49 例3-32,3-34,解:每次傳送數(shù)據(jù)的的過程相同,可用循環(huán)程序?qū)崿F(xiàn)。 30H4FH共32個(gè)單元,循環(huán)次數(shù)應(yīng)為32次(保存在R2中),為了方便每次傳送數(shù)據(jù)時(shí)地址的修改,送片內(nèi)RAM數(shù)據(jù)區(qū)首地址送R0,片外RAM數(shù)據(jù)區(qū)首地址送DPTR。程序流程圖如右圖所示。,程序如下: ORG 1000H START: MOV R0, #30H MOV DPTR, #2000H MOV R2, #20H ; 設(shè)置循環(huán)次數(shù) LOOP: MOV A, R0 ; 將片內(nèi)RAM數(shù)據(jù)區(qū)內(nèi)容送A MOVX DPTR, A ; 將A的內(nèi)容

41、送片外RAM數(shù)據(jù)區(qū) INC R0 ; 源地址遞增 INC DPTR ; 目的地址遞增 DJNZ R2, LOOP ; 若R2的不為0,則轉(zhuǎn)到LOOP處 繼續(xù)循環(huán);否則循環(huán)結(jié)束 SJMP $ END,4.4 循環(huán)結(jié)構(gòu)程序,例4.12 已知80C51單片機(jī)作用的晶振為6MHz,要設(shè)計(jì) 一個(gè)軟件延時(shí)程序,延時(shí)時(shí)間為10ms。同書P63例4-11 分析:延時(shí)時(shí)間主要與兩個(gè)因素有關(guān): (1)所用晶振; (2)延時(shí)程序中的循環(huán)次數(shù)。 現(xiàn)已知晶振為6MHz,則可知一個(gè)機(jī)器周期為2s,那么DJNZ指令為2個(gè)機(jī)器周期,共4s,采用單重循環(huán)要循環(huán)250次,可實(shí)現(xiàn)1ms的延時(shí),1ms則再用一循環(huán),循環(huán)10次,可得1

42、0ms延時(shí)。,4.4 循環(huán)結(jié)構(gòu)程序,圖4-7 延時(shí)程序框圖,4.4 循環(huán)結(jié)構(gòu)程序,解 本例采用循環(huán)體為兩NOP指令,則 (1+1+2)2sMT=1ms,MT=125=7DH ORG 2000H MOV R0,#0AH ;毫秒數(shù)R0 DL2:MOV R1,#MT ;1ms延時(shí)的預(yù)定值MTR1 DL1:NOP NOP DJNZ R1,DL1 ;1ms延時(shí)循環(huán) DJNZ R0,DL2 ;毫秒數(shù)減1,不等于0則繼續(xù)循環(huán),等于0結(jié)束 END,4.4 循環(huán)結(jié)構(gòu)程序,若考慮其他指令的執(zhí)行時(shí)間,則該段延時(shí)程序的精確延時(shí)時(shí)間計(jì)算如下: 2s1(12)2s (112)2s125 10 =10062s 若需要延時(shí)更

43、長時(shí)間,可采用更多重循環(huán),如1s延時(shí)可用3重循環(huán),而7重循環(huán)可延時(shí)1年。 注意:在采用軟件實(shí)現(xiàn)延時(shí)功能時(shí),不允許使用中斷,否則將影響定時(shí)精度。,例題 編制程序設(shè)計(jì)50ms延時(shí)程序。,解:延時(shí)程序與51系列指令執(zhí)行時(shí)間(機(jī)器周期數(shù))和晶振頻率fOSC有直接的關(guān)系。當(dāng)fOSC=12MHz時(shí),機(jī)器周期為1s,執(zhí)行一條DJNZ指令需要2個(gè)機(jī)器周期,時(shí)間為2s。 50ms2s255,因此單重循環(huán)程序無法實(shí)現(xiàn),可采用雙重循環(huán)的方法編寫50ms延時(shí)程序。,程序如下: ORG 1000H DELAY: MOV R7, #200 ; 設(shè)置外循環(huán)次數(shù)(此條指令需要1個(gè) 機(jī)器周期) DLY1: MOV R6, #1

44、23 ; 設(shè)置內(nèi)循環(huán)次數(shù) DLY2: DJNZ R6, DLY2 ;(R6)1=0,則順序執(zhí)行,否則轉(zhuǎn) 回DLY2繼續(xù)循環(huán),延時(shí)時(shí)間為 2s123=246s NOP ; 延時(shí)時(shí)間為1s DJNZ R7,DLY1 ;(R7)1=0,則順序執(zhí)行,否則轉(zhuǎn) 回DLY1繼續(xù)循環(huán),延時(shí)時(shí)間為 (246211)20021=50.003ms RET ; 子程序結(jié)束 END,4.4 循環(huán)結(jié)構(gòu)程序,例4.13 將20H單元內(nèi)的兩個(gè)BCD數(shù)相乘,相乘的結(jié)果要求仍為BCD數(shù),乘積存入21H單元。 分析:兩個(gè)BCD數(shù)最大的是99,99=81。若采用“MUL”指令,則結(jié)果為51H,而對(duì)乘法沒有十進(jìn)制調(diào)整指令。所以,在此必

45、須采用加法與十進(jìn)制調(diào)整指令重復(fù)執(zhí)行的方法。,4.4 循環(huán)結(jié)構(gòu)程序,圖4-8 BCD數(shù)乘法流程圖,4.4 循環(huán)結(jié)構(gòu)程序,解 ORG 2000H MOV A,20H ANL A,#0FH;把BCD數(shù)的低位分離出來 MOV R0,A MOV A,20H SWAP A;變換BCD數(shù)的高低位 ANL A,#0FH;把BCD數(shù)的高位分離出來 MOV R1,A CLR A;清A,4.4 循環(huán)結(jié)構(gòu)程序,LP:ADD A,R1 DA A DJNZ R0,LP ;R0個(gè)R1相加 MOV 21H,A LP1:SJMP LP1 END 本程序中,循環(huán)體只有ADD、DA、DJNZ 3條指令,這3條指令的作用是把乘法變?yōu)?/p>

46、累加。,4.4 循環(huán)結(jié)構(gòu)程序,例4.14 冒泡程序。 設(shè)有n個(gè)數(shù),分別存放在RAM中LIST地址開始的連續(xù)存儲(chǔ)單元中,要求將n個(gè)數(shù)比較大小之后,按由小到大的次序排列,再存入原存儲(chǔ)區(qū)。設(shè)n=7,參與比較的數(shù)為0,13,3,90,27,32,11。 分析: 依次將相鄰兩個(gè)單元的內(nèi)容進(jìn)行比較。即第一個(gè)數(shù)與第二個(gè)數(shù)進(jìn)行比較,第二個(gè)數(shù)與第三個(gè)數(shù)進(jìn)行比較,依此進(jìn)行,如符合由小到大的順序,則不改變它們?cè)趦?nèi)存中的位置,否則交換它們之間的位置。如此反復(fù)比較,直到數(shù)列排完為止。,4.4 循環(huán)結(jié)構(gòu)程序,由于在比較過程中,小數(shù)向上冒,因此這種排序程序稱為“冒泡程序”,比較過程如下:,4.4 循環(huán)結(jié)構(gòu)程序,第一輪經(jīng)過6

47、次兩兩比較,得到一個(gè)最大數(shù);第二輪經(jīng)過5次兩兩比較,得到一個(gè)次大數(shù); 依此類推。每輪比較后得到本輪最大數(shù),該數(shù)就不再參與下一輪的比較,故每輪比較次數(shù)減1。為加快排序速度,程序中設(shè)置一個(gè)標(biāo)志位,只要在比較過程中兩數(shù)之間沒有發(fā)生過交換,就表示數(shù)列已按由小到大的順序排列好了,就可以結(jié)束比較。,4.4 循環(huán)結(jié)構(gòu)程序,圖4-9 冒泡程序流程圖,4.4 循環(huán)結(jié)構(gòu)程序,設(shè)數(shù)列首地址存于R0中,R2為外循環(huán)次數(shù)計(jì)數(shù)器,R3為內(nèi)循環(huán)次數(shù)計(jì)數(shù)器,R1為交換標(biāo)志。 解 ORG 0050H LIST DB 0,13,3,90,27,32,11 CNT EQU 07H ORG 8000H MOV R2,#CNT-1 ;

48、數(shù)列個(gè)數(shù)減1,這里(R2)=7-1,4.4 循環(huán)結(jié)構(gòu)程序,LOOP1: MOV A,R2 ;外循環(huán)計(jì)數(shù)值 MOV R3,A ;內(nèi)循環(huán)計(jì)數(shù) MOV R1,#01H ;交換標(biāo)志位 LOOP2:MOV A,R0;取數(shù)據(jù) MOV B,A ;暫存B INC R0 CLR C SUBB A,R0 ;兩數(shù)比較 JC LESS ;XiXi+1轉(zhuǎn)LESS,4.4 循環(huán)結(jié)構(gòu)程序,MOV A,B ;取大數(shù) XCH A,R0 ;兩數(shù)交換位置 DEC R0 MOV R0,A INC R0 ;恢復(fù)數(shù)據(jù)指針 MOV R1,#02H;置交換標(biāo)志位為2 LESS:DJNZ R3,LOOP2 ;內(nèi)循環(huán)計(jì)數(shù)減1,判一遍查完? DJ

49、NZ R2,LOOP3;外循環(huán)計(jì)數(shù)減1,判排序結(jié)束? STOP:RET,4.4 循環(huán)結(jié)構(gòu)程序,LOOP3:DJNZ R1,LOOP1 ;發(fā)生交換轉(zhuǎn)移 SJMP STOP END 練習(xí)題:200名學(xué)生參加考試,成績放在80C51的外部RAM的一個(gè)連續(xù)存儲(chǔ)單元,95100分頒發(fā)A級(jí)證書,9094分頒發(fā)B級(jí)證書,低于90分不計(jì)。編寫程序,統(tǒng)計(jì)獲A、B級(jí)證書的人數(shù)。將結(jié)果存入內(nèi)部RAM的兩個(gè)單元。 注意:地址指針的分配 參考程序:,4.4 循環(huán)結(jié)構(gòu)程序,ORG 0030H EGX DATA 1000H;存放成績的外部連續(xù)存儲(chǔ)單元起始地址 GA DATA 20H;設(shè)置存放獲取A級(jí)證書人數(shù)的單元 GB D

50、ATA 21H;設(shè)置存放獲取B級(jí)證書人數(shù)的單元 MOV GA,#00 MOV GB,#00 MOV DPTR,#EGX ;初始化,數(shù)據(jù)塊首地址 MOV R2,#200 ;定義計(jì)數(shù)器,200名學(xué)生數(shù) LOOP: MOVX A,DPTR CJNE A,#95, LOOP1,4.4 循環(huán)結(jié)構(gòu)程序,LOOP1:JNC NEXT1 ;C=0,A=95轉(zhuǎn)至NEXT1 CJNE A,#90,LOOP2 LOOP2:JC NEXT INC GB SJMP NEXT NEXT1:INC GA NEXT:INC DPTR DJNZ R2,LOOP SJMP $ END,4.5 子程序結(jié)構(gòu),4.5 子程序結(jié)構(gòu) 一、

51、概念 子程序:完成確定任務(wù),并能為其他程序反復(fù)調(diào)用的程序段。 要求子程序在結(jié)構(gòu)上具有通用性和獨(dú)立性。例如:代碼轉(zhuǎn)換,運(yùn)算程序,任意數(shù)的平方等。 子程序的調(diào)用與返回: 主程序調(diào)用子程序的過程:在主程序中需要執(zhí)行這種操作的地方執(zhí)行一條調(diào)用指令(LCALL或ACALL),轉(zhuǎn)到子程序,而完成規(guī)定的操作后,再在子程序最后應(yīng)用RET返回指令返回到主程序斷點(diǎn)處,繼續(xù)執(zhí)行下去。,4.5 子程序結(jié)構(gòu),子程序的調(diào)用 子程序的入口地址:子程序的第一條指令地址,常用標(biāo)號(hào)表示。 程序的調(diào)用過程:單片機(jī)收到ACALL或LCALL指令后,首先將當(dāng)前的PC值(調(diào)用指令的下一條指令的首地址)壓入堆棧保存(低8位先進(jìn)棧,高8位后

52、進(jìn)棧),然后將子程序的入口地址送入PC,轉(zhuǎn)去執(zhí)行子程序。 子程序的返回 主程序的斷點(diǎn)地址:子程序執(zhí)行完畢后,返回主程序的地址,它在堆棧中保存。 子程序的返回過程:子程序執(zhí)行到RET指令后,將壓入堆棧的斷點(diǎn)地址彈回給PC(先彈回PC的高8位,后彈回PC的低8位),使程序回到原先被中斷的主程序地址(斷點(diǎn)地址)去繼續(xù)執(zhí)行。,4.5 子程序結(jié)構(gòu),注意:中斷服務(wù)程序是一種特殊的子程序,它是在計(jì)算機(jī)響應(yīng)中斷時(shí),由硬件完成調(diào)用而進(jìn)入相應(yīng)的中斷服務(wù)程序。RETI指令與RET指令相似,區(qū)別在于RET是從子程序返回,RETI是從中斷服務(wù)程序返回。 子程序優(yōu)點(diǎn): 簡化了程序的邏輯結(jié)構(gòu); 提高編程效率,便于調(diào)試; 節(jié)

53、省存儲(chǔ)器的空間。,4.5 子程序結(jié)構(gòu),與子程序調(diào)用有關(guān)的指令: 兩條調(diào)用子程序指令: ACALL addr11;LCALL addr16一條返回主程序指令:RET 二、子程序設(shè)計(jì)要點(diǎn) 1、第一條語句前必須有標(biāo)號(hào)。 2、子程序最后應(yīng)以返回指令(RET)結(jié)尾。 3、在主程序中設(shè)置堆棧。 凡有子程序的程序,主程序初始化一定要設(shè)置棧底和棧區(qū),以免造成混亂和錯(cuò)誤。因調(diào)用子程序時(shí),主程序的斷點(diǎn)將自動(dòng)入棧,轉(zhuǎn)入子程序后,現(xiàn)場的保護(hù)都要占用堆棧工作單元。,4.5 子程序結(jié)構(gòu),4、保護(hù)和恢復(fù)現(xiàn)場 在轉(zhuǎn)入子程序時(shí),特別是進(jìn)入中斷服務(wù)子程序時(shí),要特別注意保護(hù)現(xiàn)場的問題。主程序使用的A、DPTR、PWS、R0R7等,

54、不應(yīng)因轉(zhuǎn)入子程序而改變。 若兩者使用的寄存器有沖突,則必須在轉(zhuǎn)入子程序后首先保護(hù)現(xiàn)場,即把要保護(hù)的單元壓堆棧;返回主程序前恢復(fù)現(xiàn)場,即出棧。,4.5 子程序結(jié)構(gòu),5、參數(shù)傳遞 指調(diào)用子程序時(shí),主程序應(yīng)把有關(guān)的參數(shù)(入口參數(shù))存放在約定的位置,子程序在執(zhí)行時(shí),可以從約定的位置取得參數(shù),當(dāng)子程序執(zhí)行完,將得到的結(jié)果(出口參數(shù))存入約定的位置,返回主程序后,主程序可以從這些約定的位置上取得需要的結(jié)果。,4.5 子程序結(jié)構(gòu),幾種參數(shù)傳遞方法: 用A或寄存器傳遞;(如:例4.15) 用地址指針寄存器(R0、R1、DPTR)傳遞;(如:例4.16) 用堆棧傳遞參數(shù)。(如:例4.17) 三、子程序的嵌套 在

55、實(shí)際應(yīng)用中,子程序中調(diào)用子程序的情況。,4.5 子程序結(jié)構(gòu),四、舉例 例4.15 設(shè)a、b、c分別存放在內(nèi)部RAM的40H、41H、42H單元中,a、b均小于10。試編程計(jì)算: 分析:用子程序來實(shí)現(xiàn)某數(shù)的平方,即通過調(diào)用子程序查平方表,結(jié)果在主程序中得到。,4.5 子程序結(jié)構(gòu),圖4-10 程序框圖,4.5 子程序結(jié)構(gòu),主程序: MAIN: MOV A,40H ACALL SQR ;調(diào)查表子程序MOV R1,A ;a2暫存R1中MOV A,41H ACALL SQR ;調(diào)查表子程序ADD A,R1MOV 42H,ASJMP $ ;等待,4.5 子程序結(jié)構(gòu),子程序: SQR: INC A MOVC

56、 A,A+PC ;查平方表 RET ;單字節(jié) TAB: DB 0,1,4,9,16 DB 25,36,49,64,81 該程序中子程序的入口條件(A)=待查表的數(shù),出口條件(A)=待查表數(shù)的平方。,4.5 子程序結(jié)構(gòu),例4.16 求兩個(gè)無符號(hào)數(shù)據(jù)塊中的最大值。數(shù)據(jù)塊的首地址分別為60H和70H,每個(gè)數(shù)據(jù)塊的第一個(gè)字節(jié)都存放數(shù)據(jù)塊長度。結(jié)果存入5FH單元。 分析:可采用分別求出兩個(gè)數(shù)據(jù)塊的最大值,然后比較其大小的方法。 求最大值的過程可采用子程序。 子程序的入口條件是數(shù)據(jù)塊首地址,返回參數(shù)即為最大值,放在A中。,4.5 子程序結(jié)構(gòu),解:主程序: ORG 2000HMOV R1,#60H ;置入口

57、條件參數(shù)ACALL QMAX ;調(diào)用求最大值子程序MOV 40H,A ;第一個(gè)數(shù)據(jù)塊的最大值暫存40H MOV R1,#70H ;置入口條件參數(shù)ACALL QMAX ;調(diào)求最大值子程序CJNE A,40H,NEXT ;兩個(gè)最大值進(jìn)行比較NEXT:JNC LP ;A大則轉(zhuǎn)LP MOV A,40H ;A小則把40H單元中的內(nèi)容送入A LP: MOV 5FH,A;把兩個(gè)數(shù)據(jù)塊的最大值送入5FH SJMP $,4.5 子程序結(jié)構(gòu),子程序: ORG 2200HQMAX:MOV A,R1 ;取數(shù)據(jù)塊長度MOV R2,A ;設(shè)置計(jì)數(shù)值CLR A ;設(shè)0為最大值,最大值放入A中 LP1:INC R1 ;修改地

58、址指針 CLR C SUBB A,R1 ;兩數(shù)相減 JNC LP3 ;原數(shù)仍為最大值,轉(zhuǎn)LP3 MOV A,R1 ;否,用此數(shù)代替最大值 SJMP LP4 ;無條件轉(zhuǎn)LP4 LP3: ADD A,R1 ;恢復(fù)原最大值 LP4: DJNZ R2,LP1 ;若沒比較完,繼續(xù)比較 RET ;比較完,返回,4.5 子程序結(jié)構(gòu),例4.17 在50H單元中存放著兩個(gè)十六進(jìn)制數(shù)字,編程使它們分別轉(zhuǎn)換成ASC碼,并存入51H和52H單元。 解:十六進(jìn)制數(shù)轉(zhuǎn)換成ASC碼的過程可采用子程序。這里采用堆棧來傳遞參數(shù)。 主程序:ORG 2000HMOV SP,#3FH;設(shè)堆棧指針PUSH 50H ;把50H單元內(nèi)的數(shù)壓入堆棧ACALL HASC ;調(diào)子程序,并把主程序的斷點(diǎn)地址高、低位(PCH、PCL)分別壓入41H、42H單元 POP 51H ;把已轉(zhuǎn)換的低半字節(jié)的ASC碼彈入51H單元,接下頁,4.5 子程序結(jié)構(gòu),MOV A,50H SWAP

溫馨提示

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

評(píng)論

0/150

提交評(píng)論