版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第3章51系列單片機(jī)指令系統(tǒng)和匯編語言程序示例3.151系列單片機(jī)指令系統(tǒng)概述3.2尋址方式3.3數(shù)據(jù)傳送類指令3.4算術(shù)運(yùn)算類指令3.5邏輯運(yùn)算及移位指令3.6控制轉(zhuǎn)移類指令3.7子程序調(diào)用與返回指令3.8位操作類指令3.9匯編程序格式與偽指令3.10匯編程序設(shè)計(jì)示例習(xí)題三3.1
51系列單片機(jī)指令系統(tǒng)概述3.1.1指令與指令系統(tǒng)的概念指令是使計(jì)算機(jī)內(nèi)部執(zhí)行相應(yīng)動(dòng)作的一種操作,是提供給用戶編程使用的一種命令。指令由構(gòu)成計(jì)算機(jī)的電子器件特性所決定,計(jì)算機(jī)只能識別二進(jìn)制代碼,以二進(jìn)制代碼來描述指令功能的語言,稱之為機(jī)器語言。由于機(jī)器語言不便于人們識別、記憶、理解和使用,因而給每條機(jī)器語言指令賦予助記符號來表示,這就形成了匯編語言。計(jì)算機(jī)能夠執(zhí)行的全部操作所對應(yīng)的指令集合,稱之為這種計(jì)算機(jī)的指令系統(tǒng)。從指令是反映計(jì)算機(jī)內(nèi)部的一種操作的角度來看,指令系統(tǒng)全面展示了計(jì)算機(jī)的操作功能,也就是它的工作原理;從用戶使用的角度來看,指令系統(tǒng)是提供給用戶使用計(jì)算機(jī)功能的軟件資源。要讓計(jì)算機(jī)處理問題,首先要編寫程序。編寫程序?qū)嶋H上是從指令系統(tǒng)中挑選一個(gè)指令子集的過程。因此,學(xué)習(xí)指令系統(tǒng)時(shí),既要從編程使用的角度掌握指令的使用格式及每條指令的功能,又要掌握每條指令在計(jì)算機(jī)內(nèi)部的微觀操作過程(即工作原理),從而進(jìn)一步加深對硬件組成原理的理解。指令一般有功能、時(shí)間和空間三種屬性。功能屬性是指每條指令都對應(yīng)一個(gè)特定的操作功能;時(shí)間屬性是指一條指令執(zhí)行所用的時(shí)間,一般用機(jī)器周期來表示;空間屬性是指一條指令在程序存儲器中存儲時(shí)所占用的字節(jié)數(shù)。指令的描述形式一般有兩種:機(jī)器語言形式和匯編語言形式?,F(xiàn)在描述計(jì)算機(jī)指令系統(tǒng)及實(shí)際應(yīng)用中主要采用匯編語言形式。采用機(jī)器語言編寫的程序稱之為目標(biāo)程序。采用匯編語言編寫的程序稱之為源程序。計(jì)算機(jī)能夠直接識別并執(zhí)行的只有機(jī)器語言。匯編語言程序不能被計(jì)算機(jī)直接識別并執(zhí)行,必須經(jīng)過一個(gè)中間環(huán)節(jié)把它翻譯成機(jī)器語言程序,這個(gè)中間過程叫做匯編。匯編有兩種方式:機(jī)器匯編和手工匯編。機(jī)器匯編是用專門的匯編程序,在計(jì)算機(jī)上進(jìn)行翻譯;手工匯編是編程員把匯編語言指令逐條翻譯成機(jī)器語言指令。現(xiàn)在主要使用機(jī)器匯編,有時(shí)也會用到手工匯編。從上述指令與指令系統(tǒng)基本概念的介紹中可以看出,學(xué)習(xí)指令系統(tǒng)時(shí),應(yīng)掌握每條指令的功能、內(nèi)部微觀操作過程、匯編語言描述的指令格式及其對應(yīng)的機(jī)器碼、時(shí)間和空間屬性等內(nèi)容。3.1.2
51單片機(jī)指令系統(tǒng)及其指令格式
51單片機(jī)指令系統(tǒng)具有功能強(qiáng)、指令短、執(zhí)行快等特點(diǎn),共有111條指令。從功能上可將指令系統(tǒng)劃分成數(shù)據(jù)傳送、算術(shù)運(yùn)算、邏輯操作、程序轉(zhuǎn)移、位操作等5大類;從空間屬性上可分為單字節(jié)指令(49條)、雙字節(jié)指令(46條)和最長的三字節(jié)指令(只有16條);從時(shí)間屬性上可分為單機(jī)器周期指令(64條)、雙機(jī)器周期指令(45條)和只有乘、除法兩條4個(gè)機(jī)器周期的指令??梢?51單片機(jī)指令系統(tǒng)在存儲空間和執(zhí)行時(shí)間方面具有較高的效率。在51單片機(jī)指令系統(tǒng)中,有豐富的位操作(或稱布爾處理)指令,形成了一個(gè)完整的位操作指令子集,成為該指令系統(tǒng)的一大特色。這會給需要進(jìn)行大量位處理的程序帶來明顯的便捷。指令系統(tǒng)中的指令描述了不同的操作,不同的操作對應(yīng)不同的指令。但從組成結(jié)構(gòu)上看,每條指令通常由操作碼和操作數(shù)兩部分組成。操作碼表示計(jì)算機(jī)執(zhí)行該指令將進(jìn)行何種操作,操作數(shù)表示參加操作的數(shù)的本身或操作數(shù)所在的地址。
51單片機(jī)的指令有無操作數(shù)、單操作數(shù)、雙操作數(shù)三種情況。匯編語言指令有如下的格式:[標(biāo)號:]操作碼助記符[目的操作數(shù)][,源操作數(shù)][;注釋]為便于后面的學(xué)習(xí),在這里先對描述指令的一些符號的約定意義加以說明。
(1)Ri和Rn:表示當(dāng)前工作寄存器區(qū)中的工作寄存器,i取0或1,表示R0或R1;n取0~7,表示R0~R7。
(2)#data:表示包含在指令中的8位立即數(shù)。
(3)#data16:表示包含在指令中的16位立即數(shù)。
(4)rel:以補(bǔ)碼形式表示的8位相對偏移量,范圍為-128~127,主要用在相對尋址的指令中。
(5)addr16和addr11:分別表示16位直接地址和11位直接地址。
(6)direct:表示直接尋址的地址。
(7)bit:表示可位尋址的直接位地址。
(8)(X):表示X單元中的內(nèi)容。
(9)((X)):表示以X單元的內(nèi)容為地址的存儲器單元內(nèi)容,即(X)作地址,該地址單元的內(nèi)容用((X))表示。
(10)/和→:“/”表示對該位操作數(shù)取反,但不影響該位的原值;“→”表示操作流程,將箭尾一方的內(nèi)容送入箭頭所指另一方的單元中。3.2尋址方式所謂尋址方式,就是CPU執(zhí)行一條指令時(shí)怎樣找到該指令所要求的操作數(shù)的方式。操作數(shù)總是存放在某一存儲單元中,找操作數(shù)實(shí)際就是尋找操作數(shù)所在的單元地址,因此就稱之為尋址方式。指令通常由操作碼和操作數(shù)構(gòu)成,操作數(shù)部分實(shí)際上只指出操作數(shù)的尋址方式。所以,尋址方式是指令的重要組成內(nèi)容。深刻理解尋址方式對后面學(xué)習(xí)指令系統(tǒng)是非常重要的。一種計(jì)算機(jī)的尋址方式的種類是由它的硬件結(jié)構(gòu)決定的,尋址方式越多樣、靈活,指令系統(tǒng)將越有效,用戶編程也越方便,計(jì)算機(jī)的功能也隨之越強(qiáng)。51系列單片機(jī)有7種尋址方式:立即尋址、寄存器尋址、寄存器間接尋址、直接尋址、基址寄存器加變址寄存器間接尋址、相對尋址和位尋址。3.2.1立即尋址操作數(shù)直接出現(xiàn)在指令中,緊跟在操作碼的后面,作為指令的一部分與操作碼一起存放在程序存儲器中,可以立即得到并執(zhí)行,不需要經(jīng)過別的途徑去尋找,故稱為立即尋址。在匯編指令中,在一個(gè)數(shù)的前面冠以“#”符號作前綴,就表示該數(shù)為立即尋址。3.2.2寄存器尋址在指令選定的某寄存器中存放或讀取操作數(shù),以完成指令規(guī)定的操作,稱為寄存器尋址。3.2.3寄存器間接尋址由指令指出某一寄存器的內(nèi)容作為操作數(shù)地址的尋址方法,稱為寄存器間接尋址。這里需要強(qiáng)調(diào)的是:寄存器中的內(nèi)容不是操作數(shù)本身,而是操作數(shù)的地址,到該地址單元中才能得到操作數(shù)。寄存器起地址指針的作用。圖3.1寄存器間接尋址示意圖3.2.4直接尋址指令中直接給出操作數(shù)所在的存儲器地址,以供取數(shù)或存數(shù)的尋址方式稱為直接尋址。3.2.5變址尋址基址寄存器加變址寄存器間接尋址,簡稱變址尋址。它是以數(shù)據(jù)指針寄存器DPTR或PC作為基址寄存器,累加器A作為變址寄存器,兩者內(nèi)容相加的和作為程序存儲器地址,再尋址該單元,讀取數(shù)據(jù)。這種尋址方式常用于訪問程序存儲器中的常數(shù)表。例如:MOVCA,@A+DPTR指令中的源操作數(shù)就是這種尋址方式。該指令尋址及操作功能如圖3.2所示。圖3.2變址尋址示意圖3.2.6相對尋址相對尋址是以當(dāng)前程序計(jì)數(shù)器PC值加上指令中給出的偏移量rel而構(gòu)成實(shí)際操作數(shù)地址的尋址方法。它用于訪問程序存儲器,常出現(xiàn)在相對轉(zhuǎn)移指令中。3.2.7位尋址位尋址是在位操作指令中直接給出位操作數(shù)的地址,可以對片內(nèi)RAM中的128個(gè)位和特殊功能寄存器SFR中的93個(gè)位進(jìn)行尋址。3.3數(shù)據(jù)傳送類指令數(shù)據(jù)傳送類指令有29條,是指令系統(tǒng)中最活躍、使用最頻繁的一類指令,幾乎所有的應(yīng)用程序都要用到這類指令。為便于找到規(guī)律以理解、記憶指令,對數(shù)據(jù)傳送類指令再作如下分類:3.3.1訪問片內(nèi)數(shù)據(jù)存儲器的一般數(shù)據(jù)傳送指令該類指令的功能是實(shí)現(xiàn)數(shù)據(jù)在片內(nèi)RAM單元之間、寄存器之間、寄存器與RAM單元之間的傳送。圖3.3給出了該類指令的操作關(guān)系圖。圖3.3訪問片內(nèi)RAM的一般傳送指令操作關(guān)系圖圖3.3中,一條單向箭頭線表示一種操作,箭頭線尾是源操作數(shù),箭頭指向的是目的操作數(shù),箭頭線旁的標(biāo)識符表示對片內(nèi)RAM的某種尋址方式。因此,一條單向箭頭線,對應(yīng)一種尋址方式,就有一條“MOV”指令。雙向箭頭線可以看做兩條單向箭頭線。從圖中可以看出:立即數(shù)只能作為源操作數(shù),而不能作為目的操作數(shù);工作寄存器中的內(nèi)容只能和直接尋址方式尋址的片內(nèi)RAM單元的內(nèi)容相互傳送,不能和其它尋址方式尋址的單元進(jìn)行數(shù)據(jù)傳送;累加器A的內(nèi)容可以和寄存器間接尋址方式、直接尋址方式尋址的片內(nèi)RAM單元的內(nèi)容相互傳送;寄存器間接尋址方式尋址的片內(nèi)RAM單元的內(nèi)容可以和直接尋址方式尋址的另一個(gè)RAM單元的內(nèi)容相互傳送;直接尋址方式尋址的兩個(gè)不同地址的RAM單元的內(nèi)容可以相互傳送。16位傳送指令只有一條,它是一條給DPTR置數(shù)的指令。根據(jù)圖3.3可很快推寫出本類的16條指令。表3.1給出了這些指令及相關(guān)說明。表3.1訪問片內(nèi)RAM的一般傳送指令表例1設(shè)內(nèi)部RAM(30H)=40H,(40H)=10H,(10H)=00H,(P1)=CAH,分析以下程序執(zhí)行后各單元及寄存器、P2口的內(nèi)容。
MOVR0,#30H ;(R0)←30H
MOVA,@R0
;(A)←((R0))
MOVR1,A ;(R1)←(A)
MOVB,@R1
;(B)←((R1))
MOV@R1,P1
;((R1))←(P1)
MOVP2,P1 ;(P2)←(P1)
MOV10H,#20H
;(10H)←20H執(zhí)行上述指令后的結(jié)果為:(R0)=30H,(R1)=(A)=40H,(B)=10H,(40H)=(P1)=(P2)=CAH,(10H)=20H。3.3.2訪問片內(nèi)特殊傳送指令
1.堆棧操作指令堆棧操作有進(jìn)棧和出棧,即壓入和彈出數(shù)據(jù),常用于保存或恢復(fù)現(xiàn)場。進(jìn)棧指令用于保存片內(nèi)RAM單元(低128字節(jié))或特殊功能寄存器SFR的內(nèi)容;出棧指令用于恢復(fù)片內(nèi)RAM單元(低128字節(jié))或特殊功能寄存器SFR的內(nèi)容。該類指令共有如下兩條指令:PUSHdirect; (SP)←(SP)+1修改指針,使其指向棧頂上的一個(gè) 存數(shù)單元
((SP))←direct把直接地址單元的內(nèi)容壓入SP所 指單元內(nèi)POPdirect; (direct)←((SP))把棧頂?shù)臄?shù)據(jù)彈出到直接尋址單 元中去
(SP)←(SP)-1修改指針,指向新棧頂這兩條指令都是雙字節(jié)指令,機(jī)器碼分別為C0direct和D0direct。例2若在外部程序存儲器中2000H單元開始依次存放0~9的平方值,數(shù)據(jù)指針(DPTR)=3A00H,用查表指令取得2003H單元的數(shù)據(jù)后,要求保持DPTR中的內(nèi)容不變。完成上述功能的程序如下:
MOVA,#03H ;(A)←03H
PUSHDPH ;保護(hù)DPTR高8位入棧
PUSHDPL ;保護(hù)DPTR低8位入棧
MOVDPTR,#2000H ;(DPTR)←2000H
MOVCA,@A+DPTR ;(A)←(2000H+03H)
POPDPL
;彈出DPTR低8位
POPDPH
;彈出DPTR高8位執(zhí)行結(jié)果:(A)=09H,(DPTR)=3A00H。由此可見,雖然在程序中改變了DPTR的內(nèi)容,但利用PUSH和POP指令可對其進(jìn)行保護(hù)和恢復(fù)。需要注意的是堆棧先進(jìn)后出的原則,否則DPL與DPH彈出時(shí)互換。執(zhí)行結(jié)果:(A)=09H,(DPTR)=3A00H。由此可見,雖然在程序中改變了DPTR的內(nèi)容,但利用PUSH和POP指令可對其進(jìn)行保護(hù)和恢復(fù)。需要注意的是堆棧先進(jìn)后出的原則,否則DPL與DPH彈出時(shí)互換。
2.數(shù)據(jù)交換指令數(shù)據(jù)傳送指令一般都是將操作數(shù)自源地址單元傳送到目的地址單元,指令執(zhí)行后,源地址單元的操作數(shù)不變,目的地址單元的操作數(shù)則修改為源地址單元的操作數(shù)。交換指令數(shù)據(jù)作雙向傳送,涉及傳送的雙方互為源地址、目的地址,指令執(zhí)行后每方的操作數(shù)都修改為另一方的操作數(shù)。因此,兩操作數(shù)均未沖掉、丟失。數(shù)據(jù)交換指令共有如下5條指令:指令助記符功能操作注釋機(jī)器碼(H)
XCHA,direct
;(A)(direct)
C5direct
XCHA,@Ri
;(A)((Ri))
C6~C7
XCHA,Rn
;(A)(Rn)
C8~F
XCHDA,@Ri;(A3~0)((Ri))3~0D6、D7
SWAPA
;(A7~4)(A3~0)
C5direct該類指令前3條是字節(jié)交換指令,表明累加器A的內(nèi)容可以和內(nèi)部RAM中任何一個(gè)單元內(nèi)容進(jìn)行交換;第4條是半字節(jié)交換指令,指令執(zhí)行后,只將A的低4位和Ri間接尋址單元的低4位交換,而各自的高4位內(nèi)容保持不變;第5條指令是把累加器A的低半字節(jié)與高半字節(jié)進(jìn)行交換。有了交換指令,可使許多數(shù)據(jù)傳送更為高效、快捷,且不會丟失信息。有了交換指令,可使許多數(shù)據(jù)傳送更為高效、快捷,且不會丟失信息。例3設(shè)(R0)=30H,(30H)=4AH,(A)=28H,則執(zhí)行XCHA,@R0后,結(jié)果為(A)=4AH,(30H)=28H;執(zhí)行XCHDA,@R0后,結(jié)果為(A)=2AH,(30H)=48H;執(zhí)行SWAPA后,結(jié)果為(A)=82H。3.3.3訪問片外數(shù)據(jù)存儲器的數(shù)據(jù)傳送指令
51單片機(jī)CPU對片外擴(kuò)展的數(shù)據(jù)存儲器RAM或I/O口進(jìn)行數(shù)據(jù)傳送時(shí),必須采用寄存器間接尋址的方法,通過累加器A來完成。這類指令共有以下4條單字節(jié)指令,指令操作碼助記符都為MOVX。指令助記符 功能操作注釋機(jī)器碼(H)
MOVXA,@DPTR ;(A)←((DPTR))
E6
MOVXA,@Ri ;(A)←((Ri)) E2、E3
MOVX@DPTR,A ;((DPTR))←(A)
F0
MOVX@Ri,A ;((Ri))←(A) F2、F3前兩條指令為輸入(讀)指令,后兩條指令為輸出(寫)指令。執(zhí)行輸入指令時(shí),在P3口的第7位引腳(P3.7)上輸出RD讀有效信號。執(zhí)行輸出時(shí),在P3口的第6位引腳(P3.6)上輸出WR寫有效信號。例4設(shè)外部RAM(0203H)=FFH,分析以下指令執(zhí)行后的結(jié)果。
MOVDPTR,#0203H ;(DPTR)←0203H
MOVXA,@DPTR ;(A)←((DPTR))
MOV30H,A ;(30H)←(A)
MOVA,#0FH ;(A)←0FH
MOVX@DPTR,A ;((DPTR))←(A)執(zhí)行結(jié)果為:(DPTR)=0203H,(30H)=FFH,(0203H)=(A)=0FH。3.3.4訪問程序存儲器的數(shù)據(jù)傳送指令訪問程序存儲器的數(shù)據(jù)傳送指令又稱做查表指令,采用基址寄存器加變址寄存器間接尋址方式,把程序存儲器中存放的表格數(shù)據(jù)讀出,傳送到累加器A。該類指令共有如下兩條單字節(jié)指令,指令操作碼助記符為MOVC。指令助記符功能操作注釋機(jī)器碼
MOVCA,@A+DPTR;(A)←((A)+(DPTR)) 93H
MOVCA,@A+PC;(PC)←(PC)+1,(A)←((A)+(PC)) 83H前一條指令采用DPTR作基址寄存器,因此可以很方便地把一個(gè)16位地址送到DPTR,實(shí)現(xiàn)在整個(gè)64KB程序存儲器單元到累加器A的數(shù)據(jù)傳送。即數(shù)據(jù)表格可以存放在程序存儲器64KB地址范圍的任何地方。后一條指令以PC作為基址寄存器,CPU取完該指令操作碼時(shí)PC會自動(dòng)加1,指向下一條指令的第一個(gè)字節(jié)地址,即此時(shí)是用(PC)+1作為基址的。另外,由于累加器A中的內(nèi)容為8位無符號數(shù),這就使得本指令查表范圍只能在256個(gè)字節(jié)范圍內(nèi)(即(PC)+1H~(PC)+100H),使表格地址空間分配受到限制。同時(shí),編程時(shí)還需要進(jìn)行偏移量的計(jì)算,即計(jì)算MOVCA,@A+PC指令所在地址與表格存放首地址間的距離字節(jié)數(shù),并需要一條加法指令進(jìn)行地址調(diào)整。偏移量計(jì)算公式為偏移量=表首地址-(MOVC指令所在地址+1)例5從片外程序存儲器2000H單元開始存放0~9的平方值,以PC作為基址寄存器進(jìn)行查表,得9的平方值。設(shè)MOVC指令所在地址(PC)=1FF0H,則偏移量=2000H-(1FF0H+1)=0FH。相應(yīng)的程序如下:
MOVA,#09H ;(A)←09H
ADDA,#0FH ;用加法指令進(jìn)行地址調(diào)整
MOVCA,@A+PC ;(A)←((A)+(PC)+1)執(zhí)行結(jié)果為:(PC)=1FF1H,(A)=51H。3.4算術(shù)運(yùn)算類指令算術(shù)運(yùn)算類指令共有24條指令,包括加法、帶進(jìn)位加法、帶借位減法、加1、減1、乘除及十進(jìn)制調(diào)整指令,主要完成加、減、乘、除四則運(yùn)算,以及增量、減量和二十進(jìn)制調(diào)整操作。算術(shù)運(yùn)算結(jié)果將影響進(jìn)位標(biāo)志CY、半進(jìn)位標(biāo)志AC、溢出標(biāo)志OV。加減法運(yùn)算結(jié)果將影響CY、AC、OV,乘除運(yùn)算只影響CY、OV。只有加1和減1指令不影響這三種標(biāo)志。奇偶標(biāo)志P要由累加器A的值來確定。3.4.1加、減法指令加、減法指令包括不帶進(jìn)位加法、帶進(jìn)位加法、帶借位減法、加1和減1指令。其中前三種指令除操作碼助記符不同外,它們的兩個(gè)操作數(shù)的尋址方式組合完全相同;后兩種指令的操作數(shù)的尋址方式也基本相同。為了抓住這些特點(diǎn)來記憶指令,我們以圖3.4所示的形式進(jìn)行說明,并在表3.2集中寫出這些指令。表3.2加、減法指令表圖3.4中的連線僅表示操作碼、兩個(gè)操作數(shù)的組合關(guān)系。從圖中可以看出,不帶進(jìn)位加法、帶進(jìn)位加法、帶借位減法指令的目的操作數(shù)都只能是累加器A,源操作數(shù)可以是立即數(shù)或寄存器尋址、寄存器間接尋址、直接尋址方式所確定的片內(nèi)RAM單元的數(shù)。從表3.2中還可以看出,它們進(jìn)行的基本操作都是累加器的內(nèi)容和源操作數(shù)或源操作數(shù)單元的內(nèi)容相加或相減,帶進(jìn)位或借位的加或減還要加上或減去CY,相加后把和送到累加器A中。加1或減1指令是單操作數(shù)指令,將操作數(shù)單元的內(nèi)容加1或減1后,再送回原單元。圖3.4加、減法指令形式結(jié)構(gòu)圖(a)加、減法指令關(guān)系圖;(b)加1減1指令關(guān)系圖例6設(shè)(A)=49H,(R0)=6BH,分析執(zhí)行指令A(yù)DDA,R0后的結(jié)果。結(jié)果為:(A)=B4H,OV=1,CY=0,AC=1,P=0。例7設(shè)(A)=C3H,數(shù)據(jù)指針低位(DPL)=ABH,CY=1,分析執(zhí)行指令A(yù)DDCA,DPL后的結(jié)果。結(jié)果為:(A)=6FH,CY=1,AC=0,P=0。例8設(shè)(A)=52H,(R0)=B4H,分析執(zhí)行如下指令后的結(jié)果:
CLRC;是位操作指令,進(jìn)位位清零
SUBBA,R0結(jié)果為:(A)=9EH,CY=1,AC=1,OV=1,P=1。例9設(shè)(R0)=7EH,(7EH)=FFH,(7FH)=38H,(DPTR)=10FEH,分析逐條執(zhí)行下列指令后各單元的內(nèi)容。
INC@R0;使7EH單元內(nèi)容由FFH變?yōu)?0H
INCR0;使R0的內(nèi)容由7EH變?yōu)?FH
INC@R0;使7FH單元內(nèi)容由38H變?yōu)?9H
INCDPTR;使DPL為FFH,DPH不變
INCDPTR;使DPL為00H,DPH為11H
INCDPTR;使DPL為01H,DPH不變3.4.2十進(jìn)制調(diào)整指令
DAA;若(A)3~0>9或(AC)=1,則(A)3~0←(A)3~0+06H若(A)7~4>9或(CY)=1,則(A)7~4←(A)7~4+06H若AC=1,CY=1同時(shí)發(fā)生,或者高4位雖等于9但低4位修正后有進(jìn)位,則A應(yīng)加66H修正。十進(jìn)制調(diào)整指令是一條對二十進(jìn)制的加法進(jìn)行調(diào)整的指令。它是一條單字節(jié)指令,機(jī)器碼為D4H。兩個(gè)壓縮BCD碼按二進(jìn)制相加,必須在加法指令A(yù)DD、ADDC后,經(jīng)過本指令調(diào)整才能得到正確的壓縮BCD碼和數(shù),實(shí)現(xiàn)十進(jìn)制的加法運(yùn)算。
例10對BCD碼加法65+58→BDH進(jìn)行十進(jìn)制調(diào)整。參考程序如下:
MOVA,#65H;(A)←65
ADDA,#58H;(A)←(A)+58
DAA
;十進(jìn)制調(diào)整執(zhí)行結(jié)果:(A)=(23)BCD,(CY)=1,即:65+58=123。使用時(shí)應(yīng)注意:DA指令不能對減法進(jìn)行十進(jìn)制調(diào)整。做減法運(yùn)算時(shí),可采用十進(jìn)制補(bǔ)碼相加,然后用DAA指令進(jìn)行調(diào)整。例如:7020=70+[20]補(bǔ)=70+(100-20)=70+80=150。機(jī)內(nèi)十進(jìn)制補(bǔ)碼可采用:[x]補(bǔ)=9AH-|x|。例11設(shè)片內(nèi)RAM30H,31H單元中分別存放著兩位BCD碼表示的被減數(shù)和減數(shù),兩數(shù)相減的差仍以BCD碼的形式存放在32H單元中??捎孟旅娴某绦?qū)崿F(xiàn):
CLRC
MOVA,#9AH
SUBBA,31H;求減數(shù)的十進(jìn)制補(bǔ)碼
ADDA,30H;做十進(jìn)制補(bǔ)碼加法
DAA
;進(jìn)行BCD調(diào)整
MOV32H,A;將BCD碼的差送存32H單元3.4.3乘、除法指令乘、除法指令為單字節(jié)4周期指令,在指令執(zhí)行中是周期最長的兩條指令。
1.乘法指令
MULAB;
(B)←((A))×((B))15~8(A)←((A))×((B))7~0
CY←0機(jī)器碼:A4H乘法指令的功能是把累加器A和寄存器B中的兩個(gè)8位無符號數(shù)相乘,將乘積16位數(shù)中的低8位存放在A中,高8位存放在B中。若乘積大于FFH(255),則溢出標(biāo)志OV置1,否則OV清0。乘法指令執(zhí)行后進(jìn)位標(biāo)志CY總是零,即CY=0。
2.除法指令
DIVAB;(A)←(A)÷(B)之商,(B)←(A)÷(B)之余數(shù)
(CY)←0,(OV)←0機(jī)器碼:84H除法指令的功能是把累加器A中的8位無符號整數(shù)除以寄存器B中的8位無符號整數(shù),所得商存于累加器A中,余數(shù)存于寄存器B中,進(jìn)位標(biāo)志位CY和溢出標(biāo)志位OV均被清零。若B中的內(nèi)容為0時(shí),溢出標(biāo)志OV被置1,即OV=1,而CY仍為0。3.5邏輯運(yùn)算及移位指令邏輯運(yùn)算及移位指令共有24條,其中邏輯指令有“與”、“或”、“異或”、累加器A清零和求反等20條,移位指令有4條。該類指令中,累加器A清零和取反、移位指令都是針對累加器A進(jìn)行操作的單操作數(shù)指令。邏輯“與”、“或”、“異或”操作指令除操作碼助記符不同外,后跟兩個(gè)操作數(shù)的尋址方式組合完全相同,且有一部分尋址方式組合與加、減法指令相同。為突出這些特點(diǎn),我們以圖3.5所示形式進(jìn)行說明。圖3.5邏輯指令形式結(jié)構(gòu)圖(a)與加、減法指令尋址方式相同的邏輯指令;(b)與加、減法指令尋址方式不同的邏輯指令從圖3.5中可看出,邏輯操作指令的目的操作數(shù)可以是累加器A或直接尋址。累加器A作目的操作數(shù)時(shí),操作數(shù)的尋址方式與加、減運(yùn)算指令完全相同;直接尋址作目的操作數(shù)時(shí),源操作數(shù)只能是累加器A或立即數(shù)。這類指令的特點(diǎn)是不影響程序狀態(tài)字寄存器PSW中的算術(shù)標(biāo)志位。只有帶進(jìn)位CY循環(huán)移位指令才影響CY。所有邏輯運(yùn)算均按位進(jìn)行。表3.3中寫出了全部邏輯操作指令。表3.3邏輯操作指令表邏輯“與”指令常用于屏蔽(置0)字節(jié)中的某些位。若清除某位,則用“0”和該位相與;若保留某位,則用“1”和該位相與。例12(P1)=C5H=11000101B,屏蔽P1口高4位而保留低4位。執(zhí)行指令:ANLP1,#0FH結(jié)果為:(P1)=05H=00000101B邏輯“或”指令常用來使字節(jié)中某些位置“1”,其它位保持不變。欲置位的位用“1”與該位相或,保留不變的位用“0”與該位相或。例13若(A)=C0H,(R0)=3FH,(3FH)=0FH執(zhí)行指令:ORLA,@R0結(jié)果為:(A)=CFH=11001111B邏輯“異或”指令常用來使字節(jié)中某些位進(jìn)行取反操作,其它位保持不變。欲使某位取反,則該位與“1”相異或;欲使某位保留,則該位與“0”相異或。還可利用異或指令對某單元自身異或,以實(shí)現(xiàn)清零操作。例14若(A)=B5H=10110101B,執(zhí)行下列操作:
XRLA,#0F0H;A的高4位取反,低4位保留,
(A)=01000101B=45H
MOV30H,A;(30H)=45H
XRLA,30H;自身異或使A清零用移位指令還可以實(shí)現(xiàn)算術(shù)運(yùn)算,左移一位相當(dāng)于原內(nèi)容乘以2,右移一位相當(dāng)于原內(nèi)容除以2,但這種運(yùn)算關(guān)系只對某些數(shù)成立(請讀者自行思考)。例15設(shè)(A)=5AH=90且CY=0,則:執(zhí)行指令RLA后,(A)=B4H=180;執(zhí)行指令RRA后,(A)=2DH=45;執(zhí)行指令RLCA后,(A)=B4H=180;執(zhí)行指令RRCA后,(A)=2DH=453.6控制轉(zhuǎn)移類指令控制轉(zhuǎn)移類指令共有17條,可分為無條件轉(zhuǎn)移指令、條件轉(zhuǎn)移指令、子程序調(diào)用及返回指令。有了豐富的控制轉(zhuǎn)移類指令,就能很方便地實(shí)現(xiàn)程序向前、向后轉(zhuǎn)移,并根據(jù)條件實(shí)現(xiàn)分支運(yùn)行、循環(huán)運(yùn)行及調(diào)用子程序等。3.6.1無條件轉(zhuǎn)移指令無條件轉(zhuǎn)移指令有4條,列于表3.4中。表3.4無條件轉(zhuǎn)移指令
1.LJMP(長轉(zhuǎn)指令)
LJMP指令執(zhí)行后,程序無條件地轉(zhuǎn)向16位目標(biāo)地址(addr16)處執(zhí)行,不影響標(biāo)志位。由于指令中提供16位目標(biāo)地址,因此執(zhí)行這條指令可以使程序從當(dāng)前地址轉(zhuǎn)移到64KB程序存儲器地址空間的任意地址,故得名為“長轉(zhuǎn)移”。該指令的缺點(diǎn)是執(zhí)行時(shí)間長,字節(jié)多。
2.AJMP(絕對轉(zhuǎn)移指令)
AJMP的機(jī)器碼是由11位直接地址addr11和指令操作碼00001按下列分布組成的:該指令執(zhí)行后,程序轉(zhuǎn)移的目的地址是由AJMP指令所在位置的地址PC值加上該指令字節(jié)數(shù)2,構(gòu)成當(dāng)前PC值。取當(dāng)前PC值的高5位與指令中提供的11位直接地址將形成轉(zhuǎn)移的目的地址,即由于11位地址的范圍是00000000000~11111111111,即2KB范圍,而目的地址的高5位是PC當(dāng)前值(是固定的),因此程序可轉(zhuǎn)移的位置只能是和PC當(dāng)前值在同一2KB范圍內(nèi)的空間。本指令可以向前也可以向后轉(zhuǎn)移,指令執(zhí)行后不影響狀態(tài)標(biāo)志位。例如:若AJMP指令地址(PC)=2300H,執(zhí)行指令A(yù)JMP0FFH后,結(jié)果為:轉(zhuǎn)移目的地址(PC)=20FFH,程序向前轉(zhuǎn)到20FFH單元開始執(zhí)行。又如:若AJMP指令地址(PC)=2FFFH,執(zhí)行指令A(yù)JMP0FFH后,結(jié)果為:轉(zhuǎn)移目的地址(PC)=30FFH,程序向后轉(zhuǎn)到30FFH單元開始執(zhí)行。由上可見:若addr11相同,則AJMP指令的機(jī)器碼相同,但轉(zhuǎn)移的目的地址卻可能不同,這是因?yàn)檗D(zhuǎn)移的目的地址是由PC當(dāng)前值的高5位與addr11共同決定的。
.
SJMP(相對短轉(zhuǎn)指令)
SJMP指令的操作數(shù)rel用8位帶符號數(shù)補(bǔ)碼表示,占指令的一個(gè)字節(jié)。因?yàn)?位補(bǔ)碼的取值范圍為-128~+127,所以該指令的轉(zhuǎn)移范圍是:相對PC當(dāng)前值向前轉(zhuǎn)移128字節(jié),向后轉(zhuǎn)移127字節(jié),即轉(zhuǎn)移目的地址=SJMP指令所在地址+2+rel如在2100H單元有SJMP指令,若rel=5AH(正數(shù)),則轉(zhuǎn)移目的地址為215CH(向后轉(zhuǎn));若rel=F0H(負(fù)數(shù)),則轉(zhuǎn)移目的地址為20F2H(向前轉(zhuǎn))。這條指令的執(zhí)行不影響標(biāo)志位。它的突出優(yōu)點(diǎn)是,指令中只給出了相對轉(zhuǎn)移地址,不具體指出地址。這樣當(dāng)程序修改時(shí),只要相對地址不發(fā)生變化,該指令就不需要做任何改動(dòng)。而對于LJMP、AJMP指令,由于指令中直接給出轉(zhuǎn)移地址,在程序修改時(shí)就可能需要修改該地址,因此SJMP指令在子程序中應(yīng)用較多。用匯編語言編程時(shí),指令中的相對地址rel往往用欲轉(zhuǎn)移至的地址的標(biāo)號(符號地址)表示。用機(jī)器匯編時(shí),能自動(dòng)算出相對地址值;用手工匯編時(shí),需自己計(jì)算相對地址值rel。rel的計(jì)算公式如下:向前轉(zhuǎn)移:rel=FEH-(SJMP指令地址與目的地址差的絕對值)向后轉(zhuǎn)移:rel=FEH-(SJMP指令地址與目的地址差的絕對值)-2若rel=FEH,即目的地址就是SJMP指令的地址,在匯編指令中的偏移地址可用$符號表示。若在程序的末尾加上SJMP$(機(jī)器碼為80FEH),則程序就不會再向后執(zhí)行,造成單指令的無限循環(huán),進(jìn)入等待狀態(tài)。
4.JMP@A+DPTR(相對長轉(zhuǎn)移指令)它是以數(shù)據(jù)指針DPTR的內(nèi)容為基址,以累加器A的內(nèi)容為相對偏移量,在64KB范圍內(nèi)無條件轉(zhuǎn)移。該指令的特點(diǎn)是轉(zhuǎn)移地址可以在程序運(yùn)行中加以改變。例如,當(dāng)DPTR為確定值,根據(jù)A的不同值就可以實(shí)現(xiàn)多分支的轉(zhuǎn)移。該指令在執(zhí)行后不會改變DPTR及A中原來的內(nèi)容。例16根據(jù)累加器A的值,轉(zhuǎn)移不同處理程序的入口。
MOVDPTR,#TABLE
;表首地址送DPTRJMP@A+DPTR ;根據(jù)A值轉(zhuǎn)移
TABLE:AJMPTAB1;當(dāng)(A)=0時(shí)轉(zhuǎn)TAB1執(zhí)行
AJMPTAB2;當(dāng)(A)=2時(shí)轉(zhuǎn)TAB2執(zhí)行
AJMPTAB3;當(dāng)(A)=4時(shí)轉(zhuǎn)TAB3執(zhí)行以上程序可以根據(jù)A的內(nèi)容進(jìn)行多分支操作,由于AJMP是雙字節(jié)指令,因此A的值必須是偶數(shù)。3.6.2條件轉(zhuǎn)移指令條件轉(zhuǎn)移指令是指當(dāng)某種條件滿足時(shí),程序轉(zhuǎn)移執(zhí)行;當(dāng)條件不滿足時(shí),程序仍按原來順序執(zhí)行。轉(zhuǎn)移的條件可以是上一條指令或更前一條指令的執(zhí)行結(jié)果(常體現(xiàn)在標(biāo)志位上),也可以是條件轉(zhuǎn)移指令本身包含的某種運(yùn)算結(jié)果。由于該類指令采用相對尋址,因此程序可在以當(dāng)前PC值為中心的-128~+127的范圍內(nèi)轉(zhuǎn)移。該類指令共有8條,可以分為累加器判零條件轉(zhuǎn)移指令、比較條件轉(zhuǎn)移指令和減1條件轉(zhuǎn)移指令三類。表3.5中列出了這些指令。
1.判零條件轉(zhuǎn)移指令判零條件轉(zhuǎn)移指令以累加器A的內(nèi)容是否為0作為轉(zhuǎn)移的條件。JZ指令是為0轉(zhuǎn)移,不為0則順序執(zhí)行;JNZ指令是不為0轉(zhuǎn)移,為0則順序執(zhí)行。累加器A的內(nèi)容是否為0,是由這條指令以前的其它指令執(zhí)行的結(jié)果決定的,執(zhí)行這條指令不作任何運(yùn)算,也不影響標(biāo)志位。表3.5條件轉(zhuǎn)移指令例17將片外RAM首地址為DATA1的一個(gè)數(shù)據(jù)塊轉(zhuǎn)送到片內(nèi)RAM首地址為DATA2的存儲區(qū)中。外部RAM向內(nèi)部RAM轉(zhuǎn)送數(shù)據(jù)時(shí)一定要經(jīng)過累加器A,利用判零條件轉(zhuǎn)移正好可以判別是否要繼續(xù)傳送或者終止。完成數(shù)據(jù)傳送的參考程序如下:MOVR0,#DATA1;R0作為外部數(shù)據(jù)塊的地址指針
MOVR1,#DATA2;R1作為內(nèi)部數(shù)據(jù)塊的地址指針
LOOP:MOVXA,@R0;取外部RAM數(shù)據(jù)送入A
HERE:JZHERE ;數(shù)據(jù)為零則終止傳送
MOV@R1,A ;數(shù)據(jù)傳送至內(nèi)部RAM單元
INCR0 ;修改指針,指向下一數(shù)據(jù)地址
INCR1
SJMPLOOP ;循環(huán)取數(shù)
2.比較轉(zhuǎn)移指令比較轉(zhuǎn)移指令共有4條。這組指令是先對兩個(gè)規(guī)定的操作數(shù)進(jìn)行比較,根據(jù)比較的結(jié)果來決定是否轉(zhuǎn)移。若兩個(gè)操作數(shù)相等,則不轉(zhuǎn)移,程序順序執(zhí)行;若兩個(gè)操作數(shù)不等,則轉(zhuǎn)移。比較是做一次減法運(yùn)算,但其差值不保存,兩個(gè)數(shù)的原值不受影響,而標(biāo)志位要受到影響。利用標(biāo)志位CY作進(jìn)一步的判斷,可實(shí)現(xiàn)三分支轉(zhuǎn)移。例18當(dāng)從P1口輸入數(shù)據(jù)01H時(shí),程序繼續(xù)執(zhí)行,否則等待,直到P1口出現(xiàn)01H。參考程序如下:MOVA,#01H ;立即數(shù)01H送A
WAIT:CJNEA,P1,WAIT;(P1)≠01H,則等待
3.減1條件轉(zhuǎn)移指令減1條件轉(zhuǎn)移指令有兩條。每執(zhí)行一次這種指令,就把第一操作數(shù)減1,并把結(jié)果仍保存在第一操作數(shù)中,然后判斷是否為零。若不為零,則轉(zhuǎn)移到指定的地址單元,否則順序執(zhí)行。這組指令對于構(gòu)成循環(huán)程序是十分有用的,可以指定任何一個(gè)工作寄存器或者內(nèi)部RAM單元作為循環(huán)計(jì)數(shù)器。每循環(huán)一次,這種指令被執(zhí)行一次,計(jì)數(shù)器就減1一次。預(yù)定的循環(huán)次數(shù)不到,計(jì)數(shù)器不會為0,轉(zhuǎn)移執(zhí)行循環(huán)操作;到達(dá)預(yù)定的循環(huán)次數(shù),計(jì)數(shù)器就被減為0,順序執(zhí)行下一條指令,也就結(jié)束了循環(huán)。例19將內(nèi)部RAM從DATA單元開始的10個(gè)無符號數(shù)相加,相加結(jié)果送SUM單元保存。設(shè)相加結(jié)果不超過8位二進(jìn)制數(shù),則相應(yīng)的程序如下:MOVR0,#0AH
;設(shè)置循環(huán)次數(shù)
MOVR1,#DATA;R1作地址指針,指向數(shù)據(jù)塊首地址
CLRA;A清零
LOOP:ADDA,@R1;加一個(gè)數(shù)
INCR1;修改指針,指向下一個(gè)數(shù)
DJNZR0,LOOP
;R0減1,不為0循環(huán)
MOVSUM,A
;存10個(gè)數(shù)相加的和3.7子程序調(diào)用與返回指令有了子程序調(diào)用與返回指令,才能使模塊化程序設(shè)計(jì)得以實(shí)現(xiàn)。用一條子程序調(diào)用指令,可將程序執(zhí)行轉(zhuǎn)向子程序的入口地址。僅從轉(zhuǎn)向子程序入口看,子程序調(diào)用指令和轉(zhuǎn)移指令相似,但二者有本質(zhì)的區(qū)別:子程序調(diào)用指令使程序執(zhí)行轉(zhuǎn)向子程序入口,執(zhí)行完子程序要返回主程序繼續(xù)執(zhí)行。為了實(shí)現(xiàn)返回,執(zhí)行子程序調(diào)用指令時(shí),首先將斷點(diǎn)地址壓棧保存,然后才轉(zhuǎn)向子程序入口地址。在子程序的最后用一條子程序返回指令,使斷點(diǎn)地址得以恢復(fù),返回主程序繼續(xù)執(zhí)行。3.7.1子程序調(diào)用指令子程序調(diào)用指令有長調(diào)用和絕對調(diào)用兩條,它們都是雙周期指令。指令助記符功能操作注釋機(jī)器碼(H)長調(diào)用指令:LCALLaddr16; (PC)←(PC)+3 12addr15~8addr7~0(SP)←(SP)+1 修改堆棧指針
((SP))←(PC7~0) 返回地址低字節(jié)壓棧保存
(SP)←(SP)+1 修改堆棧指針
((SP))←(PC15~8) 返回地址高字節(jié)壓棧保存
(PC)←addr16 轉(zhuǎn)向子程序絕對調(diào)用指令:ACALLaddr11;(PC)←(PC)+2a10a9a810001addr7~0
(SP)←(SP)+1 修改堆棧指針
((SP))←(PC7~0)返回地址壓棧保存
(SP)←(SP)+1 修改堆棧指針
((SP))←(PC15~8)返回地址壓棧保存
(PC10~0)←addr11轉(zhuǎn)向子程序
LCALL和ACALL指令類似于轉(zhuǎn)移指令LJMP和AJMP,不同之處在于,它們在轉(zhuǎn)移前要把執(zhí)行完該指令的PC內(nèi)容自動(dòng)壓入堆棧后,才將子程序入口地址addr16(或addr11)送PC,實(shí)現(xiàn)轉(zhuǎn)移。LCALL與LJMP一樣提供16位地址,可調(diào)用64KB范圍內(nèi)的子程序。由于該指令為3字節(jié),因此執(zhí)行該指令時(shí)首先應(yīng)執(zhí)行(PC)←(PC)+3,以獲得下一條指令地址,并把此時(shí)的PC內(nèi)容壓入堆棧(先壓入低字節(jié),后壓入高字節(jié))作為返回地址,堆棧指針SP加2指向棧頂,然后把目的地址addr16送入PC。該指令的執(zhí)行不影響標(biāo)志位。
ACALL與AJMP一樣提供11位地址,只能調(diào)用與PC在同一2KB范圍內(nèi)的子程序。由于該指令為2字節(jié)指令,因此執(zhí)行該指令時(shí)應(yīng)執(zhí)行(PC)←(PC)+2,以獲得下一條指令地址,并把該地址壓入堆棧作為返回地址。該指令機(jī)器碼的構(gòu)成也與AJMP類似,只不過操作碼第一字節(jié)高半字節(jié)的最后一位是1。機(jī)器碼的組成如下:被調(diào)用子程序的目的地址也是由執(zhí)行ACALL指令的當(dāng)前PC值的高5位與指令中提供的11位直接地址組成的。3.7.2返回指令返回指令共兩條:一條是對應(yīng)兩條調(diào)用指令的子程序返回指令RET,另一條是對應(yīng)從中斷服務(wù)程序的返回指令RETI。從上述兩條指令的功能操作看,都是從堆棧中彈出返回地址送PC,堆棧指針減2,但它們是兩條不同的指令,有下面兩點(diǎn)不同:
(1)從使用上,RET指令必須作為子程序的最后一條指令;RETI必須作為中斷服務(wù)程序的最后一條指令。
(2)RETI指令除恢復(fù)斷點(diǎn)地址外,還恢復(fù)CPU響應(yīng)中斷時(shí)硬件自動(dòng)保護(hù)的現(xiàn)場信息。執(zhí)行RETI指令后,將清除中斷響應(yīng)時(shí)所置位的優(yōu)先級狀態(tài)觸發(fā)器,使得已申請的同級或低級中斷申請可以響應(yīng);而RET指令只能恢復(fù)返回地址。3.7.3空操作指令空操作指令是一條單字節(jié)單周期指令,即NOP;(PC)←(PC)+1它控制CPU不做任何操作,僅僅是消耗這條指令執(zhí)行所需要的一個(gè)機(jī)器周期的時(shí)間,不影響任何標(biāo)志位,故稱為空操作指令。NOP指令在設(shè)計(jì)延時(shí)程序、拼湊精確延時(shí)時(shí)間及在程序等待或修改程序等場合是很有用的。3.8位操作類指令位操作類指令在單片機(jī)指令系統(tǒng)中占有重要地位,這是因?yàn)閱纹瑱C(jī)在控制系統(tǒng)中主要用于控制線路的通、斷及繼電器的吸合與釋放等。位操作也稱布爾變量操作,它是以位(bit)為單位進(jìn)行運(yùn)算和操作的。51單片機(jī)內(nèi)部有一個(gè)功能相對獨(dú)立的布爾處理機(jī)。布爾處理機(jī)借用進(jìn)位標(biāo)志CY作為位累加器,有位存儲器(即位尋址區(qū)中的各位)。指令系統(tǒng)中有17條專門進(jìn)行位處理的指令集。位處理指令可以完成以位為對象的數(shù)據(jù)轉(zhuǎn)送、運(yùn)算、控制轉(zhuǎn)移等操作。在位操作指令中,位地址的表示有以下不同的方法(以下均以程序狀態(tài)字寄存器PSW的第5位F0標(biāo)志為例說明):
(1)直接位地址表示,如D5H。
(2)點(diǎn)表示(說明是什么寄存器的什么位),如PSW.5,說明是PSW的第5位。
(3)位名稱表示,如直接用F0表示。
(4)用戶定義名稱表示,如用戶定義用FLG這一名稱來代替F0,則在指令中允許用FLG表示F0標(biāo)志位。位操作類指令列于表3.6中。表3.6位操作類指令圖3.6硬件邏輯電路圖3.9匯編程序格式與偽指令用匯編語言編寫程序,其實(shí)質(zhì)是從指令系統(tǒng)選取并進(jìn)行組織能實(shí)現(xiàn)特定問題所要求功能的一個(gè)指令子集的過程。當(dāng)然,程序設(shè)計(jì)首先是算法的設(shè)計(jì),還要采用一些程序設(shè)計(jì)的方法。這些與采用其它任何一種語言進(jìn)行程序設(shè)計(jì)是一樣的,不再贅述。用匯編語言編寫的程序稱為源程序。它不能直接在計(jì)算機(jī)上運(yùn)行,必須經(jīng)過匯編,把它變換成機(jī)器代碼程序后才能執(zhí)行。如果采用機(jī)器進(jìn)行匯編,則需要提供如何進(jìn)行匯編的一些信息。提供這些信息的命令叫做偽指令。所以,匯編程序中除了指令系統(tǒng)中的指令外,還包含一些偽指令。
1.匯編程序格式匯編程序是指令系統(tǒng)的一個(gè)子集,只要指令按格式書寫就構(gòu)成了程序的基本格式。在程序中,指令書寫具有如下格式:[標(biāo)號:]操作碼助記符[目的操作數(shù)][,源操作數(shù)][;注釋]標(biāo)號用在指令的前邊,必須跟“:”,表示符號地址。一般,在程序中有特定用途的地方加標(biāo)號,如轉(zhuǎn)移目標(biāo)執(zhí)行指令的前面需加標(biāo)號(并不是所有指令前面都需要加標(biāo)號)。書寫匯編指令時(shí)必須注意:操作碼助記符與操作數(shù)之間至少有一個(gè)空格分隔;源操作數(shù)與目的操作數(shù)之間必須用“,”分隔;注釋是對程序的說明,其與指令之間必須用“;”分隔。
2.偽指令偽指令不要求計(jì)算機(jī)做任何操作,也沒有對應(yīng)的機(jī)器碼,不產(chǎn)生目標(biāo)程序,不影響程序的執(zhí)行,僅僅是一些能夠幫助進(jìn)行匯編的指令。它主要用來指定程序或數(shù)據(jù)的起始位置,給出一些連續(xù)存放數(shù)據(jù)的地址,為中間運(yùn)算結(jié)果保留一部分存儲空間,以及表示源程序結(jié)束等。不同版本的匯編語言其偽指令的符號和含義可能有所不同,但基本用法是相似的。下面介紹幾種常用的偽指令。
1)設(shè)置目標(biāo)程序起始地址偽指令ORG格式:[符號:]ORG地址(十六進(jìn)制表示)該偽指令的功能是規(guī)定其后面的目標(biāo)程序或數(shù)據(jù)塊的起始地址。它放在一段源程序(主程序、子程序)或數(shù)據(jù)塊的前面,說明緊跟在其后的程序段或數(shù)據(jù)塊的起始地址就是ORG后面給出的地址。例如:ORG2000H
START:MOVA,#7FH表明標(biāo)號為START的目標(biāo)程序從2000H單元開始存放,標(biāo)號START也具有2000H地址值。一般在一個(gè)匯編語言源程序的開始,都用一條ORG偽指令來規(guī)定該程序存放的起始位置。在一個(gè)源程序中,可以多次使用ORG指令,以規(guī)定不同程序段的起始位置。但所規(guī)定的地址應(yīng)從小到大,不允許不同的程序段之間有重疊。一個(gè)源程序若不用ORG指令開始,則從0000H單元開始存放目標(biāo)代碼。
2)結(jié)束匯編偽指令END格式:[符號:]END
END是匯編語言源程序的結(jié)束標(biāo)志,表示匯編結(jié)束。在END以后所寫的指令,匯編程序都不予處理。一個(gè)源程序只能有一個(gè)END命令,否則就有一部分指令不能被匯編。如果END前面加標(biāo)號的話,則應(yīng)與被結(jié)束程序段的起始點(diǎn)的標(biāo)號一致,以表示結(jié)束的是哪一個(gè)程序段。
3)定義字節(jié)偽指令DB格式:[標(biāo)號:]DB項(xiàng)或項(xiàng)表其中項(xiàng)或項(xiàng)表指一個(gè)字節(jié)數(shù)據(jù),或是用逗號分開的字節(jié)數(shù)據(jù)串,或是以引號括起來的字符串。該偽指令的功能是把項(xiàng)或項(xiàng)表的數(shù)據(jù)(字符串按字符順序以ASCII碼)存入從標(biāo)號地址開始的連續(xù)存儲單元中。例如:ORG2000H
TAB1:DB30H,8AH,7FH,73DB′5′,′A′,′BCD′由ORG2000H得TAB1的地址為2000H,因此,以上偽指令經(jīng)匯編后,將對2000H開始的連續(xù)存儲單元賦值:(2000H)=30H(2001H)=8AH(2002H)=7FH(2003H)=49H;十進(jìn)制數(shù)73以十六進(jìn)制數(shù)存放(2004H)=35H;35H是數(shù)字5的ASCII碼(2005H)=41H;41H是字母A的ASCII碼(2006H)=42H;42H是字符串′BCD′中B的ASCII碼(2007H)=43H;43H是字符串′BCD′中C的ASCII碼(2008H)=44H;44H是字符串′BCD′中D的ASCII碼
4)定義字偽指令DW格式:[標(biāo)號:]DW項(xiàng)或項(xiàng)表
DW偽指令與DB相似,但用于定義字的內(nèi)容。項(xiàng)或項(xiàng)表指所定義的一個(gè)字(兩個(gè)字節(jié))或用逗號分開的字串。匯編時(shí),機(jī)器自動(dòng)按高8位先存入,低8位在后的格式排列。例如:ORG1500H
TAB2:DW1234H,80H匯編以后:(1500H)=12H,(1501H)=34H,(1502H)=00H,(1503H)=80H。
5)預(yù)留存儲空間偽指令DS格式:[標(biāo)號:]DS表達(dá)式該偽指令的功能是從標(biāo)號地址開始,保留若干個(gè)字節(jié)的內(nèi)存空間以備存放數(shù)據(jù)。保留的字節(jié)單元數(shù)由表達(dá)式的值決定。例如:
ORG1000H
DS20H
DB30H,8FH匯編后從1000H開始,預(yù)留32(20H)個(gè)字節(jié)的內(nèi)存單元,然后從1020H開始,按照下一條DB指令賦值,即(1020H)=30H,(1021H)=8FH。
6)等值偽指令EQU格式:標(biāo)號:EQU項(xiàng)該偽指令的功能是將指令中的項(xiàng)的值賦予EQU前面的標(biāo)號。項(xiàng)可以是常數(shù)、地址標(biāo)號或表達(dá)式。例如:
TAB1:EQU1000H
TAB2:EQU2000H匯編后,TAB1、TAB2分別具有值1000H、2000H。用EQU偽指令對某標(biāo)號賦值后,該標(biāo)號的值在整個(gè)程序中不能再改變。
7)位地址定義偽指令BIT格式:標(biāo)號:BIT位地址該偽指令的功能是將位地址賦予BIT前面的標(biāo)號,經(jīng)賦值后可用該標(biāo)號代替BIT后面的位地址。例如:
PLG:BITF0
AI:BITP1.0經(jīng)以上偽指令定義后,在程序中就可以把FLG和AI作為位地址來使用。3.10匯編程序設(shè)計(jì)示例
51單片機(jī)匯編語言程序設(shè)計(jì)方法基本同別的語言程序設(shè)計(jì)一樣,而更接近IBMPC機(jī)匯編語言程序設(shè)計(jì)。限于篇幅,本節(jié)只舉一些具有51單片機(jī)匯編語言特點(diǎn)的程序作為示例,硬件特性使用的應(yīng)用程序要結(jié)合第2章的硬件知識融會貫通。3.10.1算術(shù)與邏輯處理程序例21將一個(gè)雙字節(jié)數(shù)存入片內(nèi)RAM。設(shè)該待存雙字節(jié)數(shù)高字節(jié)在工作寄存器R2中,低字節(jié)在累加器A中,要求高字節(jié)存入片內(nèi)RAM的36H單元,低字節(jié)存入35H單元,則相應(yīng)的參考程序如下:
MOVR0,#35H;R0作指向片內(nèi)RAN單元的地址指針,先指向35H單元
MOV@R0,A ;低字節(jié)存入35H單元
INCR0
;使R0指向36H單元
XCHA,R2
;R2與A的內(nèi)容交換,待存高字節(jié)交換到A中
MOV@R0,A;高字節(jié)存入36H單元,A的內(nèi)容未受影響
XCHA,R2
;R2與A的內(nèi)容再次交換,兩者的內(nèi)容恢 復(fù)原狀例22多字節(jié)無符號數(shù)相加。設(shè)被加數(shù)與加數(shù)分別在以ADR1與ADR2為初址的片內(nèi)數(shù)據(jù)存儲器區(qū)域中,自低字節(jié)起,由低到高依次存放;它們的字節(jié)數(shù)為L,要求加得的和放回被加數(shù)的單元。程序流程框圖如圖3.7所示。圖3.7例22的程序流程圖例23將R1、R2、R3、R4四個(gè)工作寄存器中的BCD碼數(shù)據(jù)依次相加,要求中間計(jì)算結(jié)果與最后的和都為BCD碼,且存入片內(nèi)RAM。設(shè)4個(gè)工作寄存器中的BCD碼數(shù)據(jù)相加后其和仍為2位BCD碼,無溢出;(R1)+(R2)后的和存入片內(nèi)RAM的30H單元,再加(R3)后的和存入31H單元,總的和存入32H單元,則主程序?yàn)?
ORG0050H
MOVR0,#30H
MOVA,R1
ADDA,R2 ;(R1)+(R2)
ACALLSUB ;調(diào)用子程序進(jìn)行BCD調(diào)整,并存和
ADDA,R3 ;(R1)+(R2)+(R3)
ACALLSUB
ADDA,R4 ;(R1)+(R2)+(R3)+(R4)
ACALLSUB子程序?yàn)?
ORG01A0H ;十進(jìn)制調(diào)整與存和子程序
SUB:MOVR7,A ;保護(hù)累加器A的內(nèi)容,以便返回 主程序繼續(xù)使用
DAA
MOV@R0,A ;把當(dāng)前和調(diào)整成BCD碼后存入
R0所指單元
INCR0 ;調(diào)整地址指針
MOVA,R7 ;恢復(fù)累加器A的內(nèi)容,使A中仍為調(diào)用子程序時(shí)的和
RET ;返主例24使雙字節(jié)數(shù)依次右移一位。設(shè)雙字節(jié)數(shù)的高字節(jié)已在工作寄存器R2,低字節(jié)已在累加器A中,則下列程序可滿足要求:
SETBC ;C預(yù)置1
XCHA,R2 ;R2與A內(nèi)容交換,高字節(jié)進(jìn)A
JBA.7,ELSE ;A.7(原R2第7位)為1轉(zhuǎn)移,否則C清零
CLRC
ELSE:RRCA ;A(原R2內(nèi)容)帶C循環(huán)右移1位,移位 ;后原R2第7位的值保持不變,原R2零
;位則進(jìn)C
XCHA,R2 ;移位后原R2內(nèi)容自A交換回R2,A內(nèi) 容自R2交換回A,準(zhǔn)備移位
RRCA
;低字節(jié)帶C(原R2零位)循環(huán)右移1位, A.0則移入C后丟失依次右移1位相當(dāng)于原數(shù)除2。程序開始時(shí)將C置1,以后又根據(jù)R2第7位是否為1而進(jìn)行分支,目的是用C的值使R2第7位保持不變,使該程序段可適合于處理帶符號的雙字節(jié)數(shù)。例25多字節(jié)數(shù)求補(bǔ)。設(shè)多字節(jié)數(shù)由低字節(jié)到高字節(jié)依次存放在片內(nèi)RAM的以30H為起始地址的區(qū)域中,求補(bǔ)后放回原處,則相應(yīng)的程序?yàn)?
ORG1000H
MOVR2,#LH;R2作循環(huán)計(jì)數(shù)器,放置待處理字節(jié)數(shù)
MOVR0,#30H ;R0作為地址指針,指向待處理首數(shù)的 地址
MOVA,@R0 ;自片內(nèi)RAM30H單元取最低字節(jié)
CPLA ;最低字節(jié)取反
ADDA,#1 ;求補(bǔ)時(shí)最低字節(jié)取反后再加1
MOV@R0,A ;最低字節(jié)取反后送存
DECR2;已處理一個(gè)字節(jié),待處理字節(jié)數(shù)減1
NEXT:INCR0 ;調(diào)整地址指針,指向下一個(gè)字節(jié)
MOVA,@R0 ;取下一個(gè)字節(jié)
CPLA ;非最低字節(jié)求補(bǔ)時(shí)只需取反
ADDCA,#0 ;本條指令的真正用意是考慮處理前一個(gè) 字節(jié)時(shí)可能有的進(jìn)位
MOV@R0,A ;本字節(jié)處理后送存
DJNZR2,NEXT ;循環(huán)處理多字節(jié)求補(bǔ)例26統(tǒng)計(jì)自P1口輸入的字串中正數(shù)、負(fù)數(shù)、零的個(gè)數(shù)。設(shè)R0、R1、R2三個(gè)工作寄存器分別為統(tǒng)計(jì)正數(shù)、負(fù)數(shù)、零的個(gè)數(shù)的計(jì)數(shù)器。完成本任務(wù)的流程框圖如圖3.8所示。圖3.8例26流程框圖匯編語言源程序如下:
START:CLRA
MOVR0,A
MOVR1,A
MOVR2,
ENTER:MOVA,P1;自P1口取一個(gè)數(shù)
JZZERO ;該數(shù)為0,轉(zhuǎn)ZERO
JBP1.0,NEG ;該數(shù)為負(fù),轉(zhuǎn)NEGINCR0 ;該數(shù)不為0、不為負(fù),則必為正數(shù),R0內(nèi)容加1SJMPENTER;循環(huán)自P1口取數(shù)ZERO:INCR2 ;零計(jì)數(shù)器加1SJMPENTERNEG:INCR1 ;負(fù)數(shù)計(jì)數(shù)器加1SJMPENTER本例所示的程序尚有缺陷:①未考慮數(shù)串中究竟有多少個(gè)數(shù),輸入不能結(jié)束;②未考慮P1口上數(shù)據(jù)輸入速度與計(jì)算機(jī)取數(shù)和分檔處理速度間的協(xié)調(diào)配合。假如已知數(shù)串的個(gè)數(shù)為L,送數(shù)的速度為每秒1個(gè),計(jì)算機(jī)取數(shù)、處理的速度極快,(與1秒比較)可忽略不計(jì),試考慮程序應(yīng)怎樣改動(dòng)。例27雙字節(jié)無符號數(shù)乘法子程序設(shè)計(jì)。算法:兩個(gè)雙字節(jié)無符號數(shù)分別放在R7、R6和R5、R4中。由于51單片機(jī)指令中只有8位數(shù)的乘法指令MUL,因此,在實(shí)現(xiàn)雙字節(jié)數(shù)乘法時(shí),可把乘數(shù)分解為(R7)(R6)=(R7)·28+(R6)(R5)(R4)=(R5)·28+(R4)則這兩個(gè)數(shù)的乘積可表示為
(R7)(R6)(R5)(R4)=[(R7)·28+(R6)]·[(R5)·28+(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)中,即可得到乘積結(jié)果。入口:(R7R6)=被乘數(shù);(R5R4)=乘數(shù);(R0)=乘積的低位字節(jié)地址指針。出口:(R0)=乘積的高位字節(jié)地址指針,指向32位積的高8位。工作寄存器:R3、R2存放部分積;R1存放進(jìn)位位。程序清單如下:
MUL1:MOVA,R6;取被乘數(shù)的低字節(jié)到AMOVB,R4 ;取乘數(shù)的低字節(jié)到BMULAB ;(R6)·(R4)
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 某混凝土重力壩課程設(shè)計(jì)
- 洗衣機(jī)課課程設(shè)計(jì)VHDL
- 混合痔中醫(yī)個(gè)案護(hù)理
- 2024年中國舞蹈室設(shè)備市場調(diào)查研究報(bào)告
- 2024至2030年電腦自動(dòng)橫切機(jī)項(xiàng)目投資價(jià)值分析報(bào)告
- 山東科瑞控股集團(tuán)有限公司目標(biāo)成本管理存在問題及對策分析
- 混凝土重力壩設(shè)計(jì)-20220510093619
- 2024至2030年往復(fù)式提升機(jī)項(xiàng)目投資價(jià)值分析報(bào)告
- 2024至2030年單雙舌鎖項(xiàng)目投資價(jià)值分析報(bào)告
- 2024年中國帶蓋品鍋市場調(diào)查研究報(bào)告
- 手術(shù)室人員管理規(guī)范
- 01中國電信云計(jì)算產(chǎn)品體系架構(gòu)
- 中國舞蹈基礎(chǔ)智慧樹知到期末考試答案章節(jié)答案2024年中國石油大學(xué)(華東)
- 年產(chǎn)1萬噸連續(xù)玄武巖纖維及其制品申請建設(shè)可行性研究報(bào)告
- 專題片創(chuàng)作與賞析智慧樹知到期末考試答案2024年
- 飲食基因與文化智慧樹知到期末考試答案2024年
- 《元旦晚會中學(xué)生》課件
- 漂流項(xiàng)目規(guī)劃設(shè)計(jì)方案
- 墻面修復(fù)施工方案
- 徐工集團(tuán)招聘測評題庫
- 初中語文九年級下冊《短詩五首-月夜》+教學(xué)課件
評論
0/150
提交評論