




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第3章單片機匯編語言程序設計3.1匯編程序與偽指令3.2基本程序設計方法3.3程序設計舉例3.4單片機編程語言與開發(fā)過程
3.1.1匯編程序
MCS—51指令所編寫的匯編語言源程序,還必須經過從匯編源程序到機器語言目標程序的“翻譯”,才能在51系列單片機運行,這種翻譯的過程稱為匯編(或稱之為編譯)。完成匯編工作有兩種途徑:一種是人工匯編;一種是機器匯編。對于量小、簡單的程序,程序員經過查指令系統(tǒng)表,將匯編源程序逐條翻譯成機器代碼,完成手工匯編,再從單片機開發(fā)裝置的鍵盤上輸入目標程序進行調試、運行;而對于量大、較復雜的程序,翻譯過程可采用計算機系統(tǒng)軟件—匯編程序完成,即機器匯編。3.1匯編程序與偽指令匯編程序是將匯編源程序轉變?yōu)橄鄳繕顺绦虻姆g程序。由于指令助記符與機器語言指令是一一對應的等價關系,所以匯編程序能很容易將匯編源程序迅速、準確、有效地翻譯成目標程序。
3.1.2偽指令在匯編源程序的過程中,還有一些指令不要求計算機進行任何操作,也沒有對應的機器碼,不產生目標程序,不影響程序的執(zhí)行,僅僅是能夠幫助匯編進行的一些指令,稱之為偽指令。它主要用來指定程序或數據的起始位置,給出一些連續(xù)存放數據的確定地址,或為中間運算結果保留一部分存儲空間以及表示源程序結束等等。不同版本的匯編語言,偽指令的符號和含義可能有所不同,但是基本用法是相似的。下面介紹幾種常用的基本偽指令。
(1)設置目標程序起始地址偽指令ORG。
格式:[標號:]ORG16位地址該偽指令的功能是規(guī)定其后面目標程序的起始地址。它放在一段源程序(主程序、子程序)或數據塊的前面,說明緊跟在其后的程序段或數據塊的起始地址就是指令中的16位地址(4位十六進制數)。例如:ORG2000HSTART:MOVA,#7FH
(2)結束匯編偽指令END。
格式:[標號:]ENDEND是匯編語言源程序的結束標志,表示匯編結束。在END以后所寫的指令,匯編程序都不予以處理。一個源程序只能有一個END命令。在同時包含有主程序和子程序的源程序中,也只能有一個END命令,并放到所有指令的最后,否則,就有一部分指令不能被匯編。
(3)定義字節(jié)偽指令DB。
格式:[標號:]DB項或項表其中項或項表指一個字節(jié),或用逗號分開的字符串,或以引號括起來的字符串(一個字符用ASCII碼表示,就相當于一個字節(jié))。該偽指令的功能是把項或項表的數值(字符則用ASCII碼)存入從標號開始的連續(xù)存儲單元中。例如:ORG2000HTAB1:DB30H,8AH,7FH,73DB′5′,′A′,′BCD′
由于ORG2000H,所以TAB1的地址為2000H,因此以上偽指令經匯編以后,將對2000H開始的若干內存單元賦值:(2000H)=30H(2001H)=8AH(2002H)=7FH
(2003H)=49H;十進制數73以十六進制數存放
(2004H)=35H;數字5的ASCII碼
(2005H)=41H;字母A的ASCII碼
(2006H)=42H;′BCD′中B的ASCII碼
(2007H)=43H;′BCD′中C的ASCII碼
(2008H)=44H;′BCD′中D的ASCII碼又如:1FFDHLJMP1234HDB30H,8AH,7FH,73,′5′,′A′,′BCD′
(4)定義字偽指令DW。
格式:[標號:]DW項或項表
DW偽指令與DB的功能類似,所不同的是DB用于定義一個字節(jié)(8位二進制數),而DW則用于定義一個字(即兩個字節(jié),16位二進制數)。在執(zhí)行匯編程序時,機器會自動按高8位先存入,低8位后存入的格式排列,這和MCS—51指令中16位數據存放的方式一致。例如:ORG1500HTAB2:DW1234H,80H
匯編以后:(1500H)=12H,(1501H)=34H,(1502H)=00H,(1503H)=80H。
(5)預留存儲空間偽指令DS。
格式:[標號:]DS表達式該偽指令的功能是從標號指定的單元開始,保留若干字節(jié)的內存空間以備源程序使用。存儲空間內預留的存儲單元數由表達式的值決定。例如:ORG1000HDS20HDB30H,8FH匯編后:從1000H開始,預留32(20H)個字節(jié)的內存單元,然后從1020H開始,按照下一條DB指令賦值,即(1020H)=30H,(1021H)=8FH。保留的存儲空間將由程序的其它部分決定它們的用處。
(6)等值偽指令EQU。
格式:標號:EQU項該偽指令的功能是將指令中項的值賦予本語句的標號。項可以是常數、地址標號或表達式。例如:TAB:EQU1000HTAB1:EQUTAB
前一條偽指令表示TAB地址的值為1000H,后一條表示符號地址TAB1與TAB等值(可以互換),需要注意的是,在同一程序中,用EQU偽指令對某標號賦值后,該標號的值在整個程序中不能再改變。
(7)位地址賦值偽指令BIT。
格式:標號BIT位地址該偽指令的功能是將位地址賦予特定位的標號,經賦值后就可用指令中BIT左面的標號來代替BIT右邊所指出的位。例如:FLG:BITF0AI:BITP1.0
經以上偽指令定義后,在編程中就可以把FLG和AI作為位地址來使用。3.2基本程序設計方法
3.2.1程序的基本結構用匯編語言進行程序設計的過程和用高級語言進行程序設計相類似。對于比較復雜的問題,首先要掌握解決它的方法和步驟——算法,有了合適的算法常??梢云鸬绞掳牍Ρ兜男Ч?其次,就是用操作框、帶箭頭流程線、框內外必要的文字說明所組成的流程圖來描述算法;最后是根據流程圖用程序設計語言來編制程序。程序的基本算法結構有3種:順序結構、分支(選擇)結構和循環(huán)結構。順序結構如圖3―1所示,虛框內A框和B框分別代表不同的操作,而且是A、B順序執(zhí)行。分支結構如圖3―2所示,它又稱為選擇結構。該結構中包含一個判斷框,根據給定條件P是否成立而選擇執(zhí)行A框操作或B框操作。條件P可以是累加器是否為零、兩數是否相等,以及測試狀態(tài)標志或位狀態(tài)等等。循環(huán)結構如圖3―3所示,它在一定的條件下,反復執(zhí)行某一部分的操作。循環(huán)結構又分為當型(While)循環(huán)結構和直到型(Until)循環(huán)結構兩種方式,見圖3―3的(a)、(b)。當型循環(huán)是先判斷條件,條件成立則執(zhí)行循環(huán)體A;而直到型循環(huán)則是先執(zhí)行循環(huán)體A一次,再判斷條件,條件不成立再執(zhí)行循環(huán)體A。
循環(huán)結構的兩種形式可以互相轉換。
圖3―1順序結構圖3―2分支結構由以上三種基本結構順序組成的算法結構,可以解決任何復雜的問題。由基本結構所構成的算法屬于結構化的算法。雖然在三種基本結構的操作框A或B中,可能是一些簡單操作,也可能還嵌套著另一個基本結構,但是不存在無規(guī)律的轉移,只在該基本結構內才存在分支和向前或向后的跳轉。圖3―3循環(huán)結構(a)當型循環(huán);(b)直到型循環(huán)
3.2.2順序結構程序設計順序結構是最簡單的一種基本結構。如果某一個需要解決的問題可以分解成若干個簡單的操作步驟,并且可以由這些操作按一定的順序構成一種解決問題的算法,則可用簡單的順序結構來進行程序設計。例1:單字節(jié)壓縮BCD碼轉換成二進制碼子程序。解:設兩個BCD碼d1d0
表示的兩位十進制數壓縮存于R2,其中R2高4位存十位,低4位存?zhèn)€位,要把其轉換成純二進制碼的算法為:(d1d0)BCD=d1×10+d0。實現該算法所編制的參考子程序如下:
入口:待轉換的BCD碼存于R2。
出口:轉換結果(8位無符號二進制整數)仍存R2。
BCD2B:ORG2000HMOVA,R2;(A)←(d1d0)BCDANLA,#0F0H;取高位BCD碼d1
SWAPA;(A)=0d1HMOVB,#0AH;(B)←10MULAB;d1×10MOVR3,A;R3暫存乘積結果
MOVA,R2;(A)←(d1d0)BCDANLA,#0FH;取低位BCD碼d0ADDA,R3;d1×10+d0
MOVR2,A;保存轉換結果
RET;子程序返回例2:雙字節(jié)壓縮BCD碼轉換成二進制碼子程序。解:該轉換的算法為:(d3d2d1d0)BCD=(d3×10+d2)×100+(d1×10+d0)
實現該算法的參考子程序如下:
入口:R5(千位、百位)、R4(十位、個位)為BCD碼。出口:R5R4(16位無符號二進制整數)。
BCD4B:ORG2100HMOVA,R5;(A)←d3d2(千位、百位)
MOVR2,A;(R2)←d3d2ACALLBCD2B;調例1子程序實現d3×10+d2→AMOVB,#64H;(B)←100MULAB;(d3×10+d2)×100MOVR6,A;R6暫存乘積低8位XCHA,B;乘積高8位送AMOVR5,A;R5暫存乘積高8位MOVA,R4;(A)←d1d0(十位、個位)MOVR2,A;(R2)←d1d0ACALLBCD2B;調例1子程序實現d1×10+d0→AADDA,R6;(A)←(R6)+(A)MOVR4,A;R4存轉換后16位數低8位MOVA,R5;(A)←(R5)ADDCA,#00H;(A)←(R5)+低8位和的進位CMOVR5,A;R5存轉換后16位數高8位RET;子程序返回
3.2.3分支(選擇)結構程序設計順序結構程序設計是最基本的程序設計技術。在實際的程序設計中,有很多情況往往還需要程序按照給定的條件進行分支。這時就必須對某一個變量所處的狀態(tài)進行判斷,根據判斷結果來決定程序的流向。這就是分支(選擇)結構程序設計。在編寫分支程序時,關鍵是如何判斷分支的條件。在MCS—51單片機指令系統(tǒng)中,有JZ(JNZ)、CJNE、JC(JNC)及JB(JNB)等豐富的控制轉移指令,它們是分支結構程序設計的基礎,可以完成各種各樣的條件判斷、分支。例3:設變量X存放在VAR單元中,函數Y存放在FUNC單元。編寫按照下式要求給Y賦值的程序。
1X>0Y=0X=0-1X<0
解:由于X為有符號數,因此可以根據它的符號位來決定其正負。判別符號位是0還是1,可利用JB或JNB指令;而判別X是否為0,則可直接用累加器判零指令JZ。完成本例題任務的程序流程框圖是由順序結構+分支結構組成的,并且在分支結構中又嵌套了另一個分支結構,從而形成了三分支而歸一的流程,如圖3―4所示。圖3―4例3程序框圖程序清單:BR1:ORG2000HMOVA,VAR;取出X送AJZCOMP;若X=0則轉移到COMPJNBACC.7,POSI;若X>0則轉移到POSIMOVA,#0FFH;若X<0則A=-1SJMPCOMP;轉分支結構出口
POSI:MOVA,#01H;X>0時A=1COMP:MOVFUNC,A;存函數Y值
HERE:AJMPHERE;結束程序例4:3個無符號單字節(jié)整數分別存于R1、R2、R3中,找出其中最大數放于R0中。解:首先將R0清零,然后進行(R1)與(R0)減法,若(R1)-(R0)>0,則(R1)>(R0),把(R1)送(R0);否則(R0)保持不變。再將(R0)分別與(R2)和(R3)比較,比較處理的方法與上面相同,這樣比較3次后,R0中即為3數中的最大數。程序清單如下:BR2:ORG2500HMOVR0,#00H;R0清零
MOVA,R1;第一個數(R1)送AACALLCOMP;比較(R1)與(R0)大小
MOVA,R2;第二個數(R2)送AACALLCOMP;比較(R2)與(R0)大小
MOVA,R3;第三個數(R3)送AACALLCOMP;比較(R3)與(R0)大小
HERE:AJMPHERECOMP:MOVR4,A;R4暫存A的內容
CLRC;清進位位CSUBBA,R0;(A)-(R0)JCM1;(A)<(R0)轉至M1MOVA,R4;恢復A值
MOVR0,A;(A)>(R0)時大數存R0M1:RET
3.1.4循環(huán)結構程序設計在解決實際問題時,往往會遇到同樣的一組操作需要重復多次的情況,這時應采用循環(huán)結構,以簡化程序,縮短程序的長度及節(jié)省存儲空間。例如,要做1到100的加法,沒有必要寫100條加法指令,而只需寫一條加法指令,使其執(zhí)行100次,每次執(zhí)行時操作數亦作相應的變化,同樣能完成原來規(guī)定的操作。循環(huán)程序一般由3部分組成:(1)置循環(huán)初值:即設置循環(huán)開始時的狀態(tài)。
(2)循環(huán)體:即要求重復執(zhí)行的部分。
(3)循環(huán)控制部分:它包括循環(huán)參數修改和依據循環(huán)結束條件判斷循環(huán)是否結束兩部分。例5:從BLOCK單元開始有一個無符號數數據塊,其長度存于LEN單元,試求出數據塊中最大的數并存入MAX單元。解:該問題解決方法與例4相同,所不同的是無符號數個數增加,即搜索尋找最大值的范圍擴大了。因此,本例題采用直到型單重循環(huán)的程序結構方式比較合理。程序框圖如圖3―5所示。圖3―5例5程序框圖程序清單:LOOP:ORG2000HMOVR0,#BLOCK;數據塊首址送R0MOVR1,LEN;數據塊長度送R1MOVMAX,#00H;存最大數單元清零
LOOP1:MOVA,MAX;(A)←(MAX)CLRC;清CSUBBA,@R0;(MAX)-((R0))JNCNEXT;若(MAX)>((R0)),則轉移
MOVMAX,@R0;若(MAX)<((R0)),則(MAX)←((R0))NEXT:INCR0;修改地址指針
DJNZR1,LOOP1;若(R1)≠0則循環(huán)搜索
RET例6:設計100ms延時程序。解:計算機執(zhí)行一條指令需要一定的時間,由一些指令組成一段程序,并反復循環(huán)執(zhí)行,利用計算機執(zhí)行程序所用的時間來實現延時,這種程序稱為延時程序。如當系統(tǒng)使用12MHz晶振時,一個機器周期為1μs,執(zhí)行一條雙字節(jié)雙周期DJNZ指令的時間為2μs,因此,執(zhí)行該指令50000次,就可以達到延時100ms的目的。對于50000次循環(huán)可采用外循環(huán)、內循環(huán)嵌套的多重循環(huán)結構。本例題的程序流程如圖3―6所示。圖3―6例6程序框圖程序清單:START:ORG1000HMOVR6,#0C8H;外循環(huán)200次
LOOP1:MOVR7,#0F8H;內循環(huán)248次
NOP;時間補償
LOOP2:DJNZR7,LOOP2;延時2μs×248=496μsDJNZR6,LOOP;延時500μs×200=100ms
RET
以上程序執(zhí)行MOVRn,#data指令的時間為1μs,DJNZ指令2μs,NOP指令1μs,所以,內循環(huán)延遲時間:1μs+1μs+2μs×248=498μs,外循環(huán)延遲時間:1μs+(內環(huán)延時+2μs)×200=100.001ms。
3.2.5子程序結構程序設計在一個程序中,將反復出現的程序段編制成一個個獨立的程序段,存放在內存中,這些完成某一特定任務可被重復調用的獨立程序段被稱為子程序。在前面所舉的例子中,已有一些程序段是以帶有RET指令的子程序形式出現的。在匯編語言編程時,恰當地使用子程序,可使整個程序的結構清楚,閱讀和理解方便,而且還可以減少源程序和目標程序的長度,不必多次重復書寫和翻譯同樣的指令。在匯編語言源程序中使用子程序,需要強調注意兩個問題,即子程序中參數傳遞和現場保護的問題。一般在匯編語言中采用的參數傳遞方法有以下3種。
(1)用累加器或工作寄存器來傳遞參數。
(2)用指針寄存器傳遞參數。
(3)用堆棧來傳遞參數。例7:將HEX單元存放的兩個十六進制數分別轉換成ASCII碼,并存入ASC和ASC+1單元。解:由于偽指令DB在匯編后,使字節(jié)以ASCII碼形式存放,所以采用查表子程序的方式來實現十六進制數到ASCII碼的轉換。轉換子程序為HASC,調用時傳遞參數采用堆棧來完成。程序清單如下:
ORG2000HPUSHHEX;第一個十六進制數入棧
ACALLHASC;調查表轉換子程序
POPASC;低4位轉換值保存
MOVA,HEX;十六進制數送ASWAPA;高4位低4位交換
PUSHA;第二個十六進制數入棧
ACALLHASC;調查表轉換子程序
POPASC+1;高4位轉換值保存
HERE:AJMPHERE;結束源程序
HASC:DECSP;DECSP;修改SP到參數位置
POPA;彈出十六進制數到AANLA,#0FH;取A低4位
ADDA,#07H;為查表進行地址調整
MOVCA,@A+PC;查表轉換
PUSHA;轉換結果入棧
INCSP;INCSP;恢復返回地址
RETASCTAB:DB′0,1,2,3,4,5,6,7′DB′8,9,A,B,C,D,E,F′END
由于堆棧操作是“先入后出”,因此,先壓入堆棧的參數應后彈出,才能保證恢復原來的狀態(tài)。例如:SUBROU:PUSHAPUSHPSWPUSHDPLPUSHDPHPOPDPHPOPDPLPOPPSWPOPARET3.3程序設計舉例
3.3.1代碼轉換程序設計前面各章節(jié)的舉例中已介紹了BCD碼與二進制數間的相互轉換以及十六進制數用查表法轉換為ASCII碼的程序設計方法。例1:十六進制數到ASCII碼的轉換子程序設計。解:該轉換的算法為:凡大于等于10的十六進制數加37H,凡小于10的十六進制數加30H,便可得到相應的ASCII碼。入口:R2(高4位為0000,低4位為0000~1111的一個十六進制數0~F)。
出口:R2(相應的ASCII碼)。程序清單如下:HASC1:MOVA,R2;十六進制數送AADDA,#0F6H;(A)+(-10)補
MOVA,R2;恢復十六進制數
JNCAD30H;若(A)<10則轉AD30HADDA,#07H;(A)≥10則先加07HAD30H:ADDA,#30H;(A)+30HMOVR2,A;ASCII碼存R2RET例2:ASCII碼到十六進制數的轉換子程序設計。解:該轉換的算法為:若為0~9的ASCII碼,則減去30H;若為A~F的ASCII碼,則減去37H,便可得到相應的十六進制數0~F。
入口:R2(0~9或A~F的ASCII碼)。出口:R2(高4位為0000,低4位為0000~1111)。程序清單如下:ASCH1:MOVA,R2;ASCII碼值送AADDA,#0D0H;(A)+(-30H)補
MOVR2,A;R2暫存減結果
ADDA,#0F6H;A+(-10)補
JNCRET1;若(A)<10轉RET1MOVA,R2;若(A)≥10則(R2)送AADDA,#0F9H;(A)+(-07H)補
MOVR2,A;十六進制數存R2RET1:RET
3.3.2運算子程序設計例3:雙字節(jié)無符號數乘法子程序設計。解:算法:兩個雙字節(jié)無符號數被分別放在R7、R6和R5、R4中。由于MCS—51指令中只有8位數的乘法指令MUL,用它來實現雙字節(jié)數相乘時,可把被乘數分解為:(R7)(R6)=(R7)·28+(R6),(R5)(R4)=(R5)·28+(R4)則這兩個數的乘積可表示為:(R7)(R6)(R5)(R4)=[(R7)·28+(R6)]·[(R5)·288+(R4)]=(R7)·(R5)·216+(R7)·(R4)·28+(R6)·(R5)·28+(R6)·(R4)=(R04)(R03)(R02)(R01)顯然,我們將(R6)·(R4)放入(R02)(R01)中,將(R7)·(R4)和(R6)·(R5)累加到(R03)(R02)中;再將(R7)·(R5)累加到(R04)(R03)中即可得到乘積結果。入口:(R7R6)=被乘數;(R5R4)=乘數;(R0)=乘積的低位字節(jié)地址指針。出口:(R0)=乘積的高位字節(jié)地址指針,指向32位積的高8位。工作寄存器:R3、R2存放部分積;R1存放進位位。程序清單如下:MUL1:MOVA,R6MOVB,R4MULAB;(R6)·(R4)MOV@R0,A;R01存乘積低8位
MOVR3,B;R3暫存(R6)·(R4)的高8位
MOVA,R7MOVB,R4MULAB;(R7)·(R4)ADDA,R3;(R7)·(R4)低8位加(R3)MOVR3,A;R3暫存28
部分項低8位MOVA,B;(R7)·(R4)高8位送AADDCA,#00H;(R7)·(R4)高8位加進位CYMOVR2,A;R2暫存28
部分項高8位MOVA,R6MOVB,R5MULAB;(R6)·(R5)ADDA,R3;(R6)·(R5)低8位加(R3)INCR0;調整R0地址為R02單元MOV@R0,A;R02存放乘積15~8位結果
MOVR1,#00H;清暫存單元
MOVA,R2ADDCA,B;(R6)·(R5)高8位加(R2)與CYMOVR2,A;R2暫存28部分項高8位
JNCNEXT;28
項向216
項無進位則轉移
INCR1;有進位則R1置1標記NEXT:MOVA,R7MOVB,R5MULAB;(R7)·(R5)ADDA,R2;(R7)·(R5)低8位加(R2)INCR0;調整R0地址為R03
MOV@R0,A;R03存放乘積23~16位結果
MOVA,BADDCA,R1;(R7)·(R5)高8位加28
項進位
INCR0;調整R0地址為R04MOV@R0,A;R04存放乘積31~24位結果
RET例4:雙字節(jié)帶符號數乘法子程序設計。解:算法:由于帶符號數乘法和無符號數乘法的基本算法是一樣的,因此可以根據入口條件調用例3MUL1子程序進行計算。不同之處有以下3點:(1)需根據被乘數和乘數的符號計算乘積的符號;(2)當被乘數和乘數為負數時,應對它們取補,形成2的補碼,然后才能調用MUL1進行運算;(3)當積為負數時,計算的結果尚需取補后才是正確的積(絕對值),積為31位。乘積符號的算法在本程序中分兩步完成:首先用ANL指令判斷兩數是否均為負,若與操作的結果為1,則兩數均為負,乘積應為正,對與的結果取反即為積的符號,存入SIG;若不屬于此情況,則用ORL指令算出積的符號存入SIG。程序中SIG、SIG1、SIG2均為內部RAM中的可尋址位。入口:(R7R6)=帶符號位被乘數;(R5R4)=帶符號位乘數;(R0)=乘積的低位字節(jié)地址指針。出口:(R0)=乘積的高位地址指針。程序清單如下:MUL2:MOVA,R7;被乘數高8位送ARLCA;(R7)的符號位送CYMOVSIG1,C;SIG1存被乘數符號
MOVA,R5;乘數高8位送ARLCA;(R5)的符號位送CYMOVSIG2,C;SIG2存放乘數符號
ANLC,SIG1;計算積的符號
JCPOSI;若兩數均負積為正則轉POSIMOVC,SIG1;計算兩數非全負時積的符號
ORLC,SIG2SJMPSIGNPOSI:CPLCSIGN:MOVSIG,C;存積的符號
MOVA,R7JBA.7,CPL1;被乘數為負轉求補
STEP1:MOVA,R5JBA.7,CPL2;乘數為負轉求補STEP2:ACALLMUL1;調(R7R6)·(R5R4)子程序
JBSIG,CPL3;積符號為負轉求補
RETCPL1:MOVA,R6;被乘數求補
CPLAADDA,#01HMOVR6,AMOVA,R7CPLAADDCA,#00HMOVR7,ASJMPSTEP1
CPL2:MOVA,R4;乘數求補
CPLAADDA,#01HMOVR4,AMOVA,R5CPLAADDCA,#00HMOVR5,ASJMPSTEP2
CPL3:DECR0;乘積結果求補
DECR0DECR0;使R0指向乘積低字節(jié)地址
MOVR2,#03H;待取補數字節(jié)數-1送R2ACALLCPL4;調用多字節(jié)數求補子程序
RET
CPL4:MOVA,@R0;多字節(jié)數求補
CPLAADDA,#01HMOV@R0,ASTEP3:INCR0MOVA,@R0CPLAADDCA,#00H
MOV@R0,ADJNZR2,STEP3;字節(jié)未轉換完轉移
RETCPL4為多字節(jié)數求補子程序,入口為(R0)=待取補數低字節(jié)地址指針;(R2)=待取補數字節(jié)數-1。出口為(R0)=求補后的高位字節(jié)地址指針。例5:雙字節(jié)無符號數除法子程序設計。解:MCS—51除法指令只能進行8位無符號數相除運算,而對于多字節(jié)除法,還需用一般的除法算法進行。常用的除法算法采用“移位相減法”,即:先設余數為0,并將被除數和余數分別左移一位,使被除數的最高位移入余數的最低位,再求(余數—除數)之差,若差為正,則令差代替余數,商為1;若差為負,則不作任何操作。然后重復以上移位相減的過程,使每位被除數都參與了運算為止。雙字節(jié)無符數除法的程序框圖如圖3-7所示。圖3―7例5程序框圖(a)除法程序框圖;(b)四舍五入處理框圖入口:(R7R6)=被除數,(R5R4)=除數。出口:(R7R6)=商數,(OVER)=溢出標志(FFH為溢出)。工作寄存器:(R3R2)=部分余數,(R1)=計數器,(R0)=差值暫存。程序清單如下:DIV:MOVA,R5;除數高8位送AJNZBEGIN;除數非零則轉BEGINMOVA,R4;除數低8位送A
JZOVER;除數為零置溢出標志
BEGIN:MOVA,R7;被除數高8位送AJNZBEGIN1;被除數非零則轉BEGIN1MOVA,R6;被除數低8位送AJNZBEGIN1;被除數非零則轉BEGIN1RET;被除數為零則返回BEGIN1:CLRA;清余數單元
MOVR2,AMOVR3,A
MOVR1,#10H;雙字節(jié)除法計數器置16DIV1:CLRC;開始R3R2R7R6左移
MOVA,R6;被除數低8位送ARLCA;R6循環(huán)左移一位
MOVR6,A;左移結果回送
MOVA,R7;被除數高8位送ARLCA;R7循環(huán)左移一位
MOVR7,A;左移結果回送
MOVA,R2;余數左移一位
RLCAMOVR2,AMOVA,R3
RLCAMOVR3,ADIV2:MOVA,R2;開始部分余數減除數
SUBBA,R4;低8位先減
MOVR0,A;暫存差值
MOVA,R3SUBBA,R5;高8位相減
JCNEXT;若部分余數<除數則轉NEXTINCR6;若部分余數≥除數則商為1MOVR3,A;新余數存R3R2MOVA,R0MOVR2,A
NEXT:DJNZR1,DIV1;16位未除完則返回
MOVA,R3;開始四舍五入處理
JBA.7,ADD1;若余數最高位為1則進1CLRC;開始余數乘2處理
MOVA,R2RLCA;余數低8位乘2MOVR2,AMOVA,R3RLCA;余數高8位乘2SUBBA,R5;余數×2-除數
JCNOOVER;若余數×2<除數則轉
JNZADD1;若夠減則轉進1
MOVA,R2;高8位相等時比較低8位
SUBBA,R4JCNOOVER;余數×2<除數則轉
ADD1:MOVA,R6;開始商進1處理
ADDA,#01HMOVR6,AMOVA,R7ADDCA,#00HMOVR7,ANOOVER:MOVOVER,#00H;清溢出標志
RETOVER:MOVOVER,#0FFH;置溢出標志
RET雙字節(jié)帶符號數除法的算法與無符號數除法的算法基本相同,所不同的是在計算除法之前先進行商的符號確定。商的符號確定方法與例4帶符號數乘法中乘積符號的確定方法相同。所以雙字節(jié)帶符號除法程序首先要進行商的符號確定,再調用無符號數除法子程序DIV即可,這里不再重復。
3.3.3查表程序設計查表,就是根據變量x,在表格中查找y,使y=f(x)。單片機應用系統(tǒng)中,查表程序是一種常用程序,它被廣泛應用于LED顯示器控制,打印機打印以及數據補償、計算、轉換等功能程序中。例6:設有一巡檢報警裝置,需要對16路值進行比較,當每一路輸入值超過該路的報警值時,實現報警。要求編制一個查表子程序,依據路數xi,查表得yi的報警值。解:xi為路數,查表時按照0,1,2,…,15取值,故為單字節(jié)規(guī)則量。
表格依xi順序列表,僅存二字節(jié)報警值yi,其表格構造見表3―1。
表3―1路數xi與報警值yi對應關系程序入口:(R2)=路數xi。
程序出口:(R4R3)=對應xi的報警值yi。
查表子程序如下:STA1:MOVA,R2;路數xi送ARLA;xi×2MOVR4,A;暫存
ADDA,#TABL(rel);加上表首偏移量
MOVCA,@A+PC;查yi第一字節(jié)
XCHA,R4;第一字節(jié)送R4ADDA,#TABL(rel)+1;形成第二字節(jié)表址
MOVCA,@A+PC;取yi第二字節(jié)
MOVR3,A;第二字節(jié)送R3RETTAB2:DW050FH,0E89H,A695H,1EAAH;報警值表
DW0D9BH,7F93H,0373H,26D7HDW2710H,9E3FH,1A66H,22E3HDW1174H,16EFH,33E4H,6CA0H
上述查表程序中使用RLA使(A)乘2,這是由于DW定義的是雙字節(jié)空間,為了保證指向正確的查表地址,所以要進行乘2處理。另外,程序中使用MOVCA,@A+PC指令,使表格偏移不得超過255個字節(jié)。當表格偏移大于255個字節(jié)時,應使用MOVCA,@A+DPTR查表指令。例7:自變量xi為雙字節(jié)規(guī)則量
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 6《比例尺》大單元整體設計(教學設計)-2024-2025學年六年級上冊數學冀教版
- 2023二年級數學上冊 七 分一分與除法第4課時 分香蕉配套教學設計 北師大版
- 2023三年級數學上冊 二 觀察物體第1課時 看一看(一)教學設計 北師大版
- 畢業(yè)論文課題答辯匯報
- 7 中華民族一家親 第一課時 (教學設計)-部編版道德與法治五年級上冊
- Unit5 Drink Lesson 1(教學設計)-2023-2024學年人教新起點版英語一年級下冊
- 胰體尾脾切除護理
- Unit 3 Lesson 2教學設計 2024-2025學年冀教版(2024)七年級英語上冊
- 2024秋九年級化學上冊 第三單元 物質構成的奧秘 課題2 原子的結構第2課時 原子核外電子的排布 離子教學設計(新版)新人教版
- 6《騎鵝旅行記(節(jié)選)》教學設計-2023-2024學年統(tǒng)編版語文六年級下冊
- 公路工程資料員培訓(總體)課件
- SY∕T 7298-2016 陸上石油天然氣開采鉆井廢物處置污染控制技術要求
- 電梯門系統(tǒng)教學課件
- 核科普知識學習考試題庫(400題)
- 六年級數學試卷講評課教學設計(共16篇)
- 線面平行判定定理
- 輪扣式模板支撐架專項施工方案
- abb繼電保護615系列操作手冊
- 甘肅省審圖機構
- 挖掘機部件英語對照表
- 辦公室口號大全
評論
0/150
提交評論