《單片機原理及應用》課件2第3章_第1頁
《單片機原理及應用》課件2第3章_第2頁
《單片機原理及應用》課件2第3章_第3頁
《單片機原理及應用》課件2第3章_第4頁
《單片機原理及應用》課件2第3章_第5頁
已閱讀5頁,還剩246頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

3.1單片機的匯編語言與指令格式3.2單片機的指令尋址方式3.3單片機的指令系統3.4匯編語言程序設計習題33.1.1匯編語言

在計算機中,指令都是以二進制數碼表示,并存放在程序存儲器中的。計算機按照程序規(guī)定的次序,依次從程序存儲器中取出要執(zhí)行的指令代碼,送到控制器的指令寄存器中對所取的指令進行分析,由控制器發(fā)出完成操作所需的一系列控制電平,指揮計算機有關部件完成相應操作。我們稱這種用二進制代碼描述指令功能的、能被計算機直接識別的語言為機器語言(MachineLanguage)。機器語言的特點是:程序簡潔、速度快、占用程序空間少、能直接被計算機識別。但也有不易記憶、書寫和閱讀不便等缺點,所以實際使用既不方便又容易出錯,很難用它進行程序設計。3.1單片機的匯編語言與指令格式為了既能保持機器語言的特點,又能方便編寫程序和閱讀程序,人們采用助記符號來代替機器指令代碼,助記符號與機器指令代碼一一對應,我們把這種編程語言稱為匯編語言(AssemblyLanguage)。需要說明的是,匯編語言是面向機器的程序設計語言,對于不同型號的計算機,有著不同結構的匯編語言;匯編語言中由于使用了助記符號,因此將由匯編語言編制的程序輸入計算機后,計算機不能像識別機器語言編寫的程序一樣直接識別和執(zhí)行匯編語言程序,必須通過預先放入計算機的“匯編程序”的加工和翻譯,才能把匯編語言程序變成能夠被計算機識別和處理的二進制代碼程序。用匯編語言等非機器語言書寫好的符號程序稱為源程序,運行時匯編程序要將源程序翻譯成機器語言程序(又稱之為目標程序)。匯編語言程序結構簡單,執(zhí)行速度快,程序易優(yōu)化,編譯后占用存儲空間小,是單片機應用系統開發(fā)中最常用的程序設計語言。匯編語言的缺點是可讀性比較差,只有熟悉單片機的指令系統,并具有一定的程序設計經驗,才能研制出功能復雜的應用程序。

相對而言,用高級語言(High-LevelLanguage),例如PL/M-51、FranklinC51、MBASIC51等編寫的程序,其可讀性強,通用性好,適用于不熟悉單片機指令系統的的用戶。3.1.2匯編語言的指令格式

MCS-51匯編語言的指令格式為

[標號:]操作碼助記符[目的操作數][,源操作數][;注釋]

其中:

[]:方括號表示該項是可選項,根據指令要求確定。

標號:用符號標明該指令所在程序存儲器的地址,并以“:”結尾,設計者根據實際需要設置。在其他指令的操作數中可以引用該標號作為地址。標號是以英文字母開頭的字母、數字和某些規(guī)定的特殊符號的序列,一般不超過8個符號。

目的操作數:表示操作的對象,是一個目標地址,也是存放操作結果的地址。目的操作數與操作碼助記符之間必須用一個以上的空格分隔。

源操作數:表示操作的對象或者是操作數的來源,可以是一個地址或者一個立即數。源操作數與目的操作數中間用逗號分隔。

注釋:是對指令或者程序段的解釋說明,用以提高程序的可讀性,注釋前必須加分號。注釋可用中文、英文或符號表示。需要強調的是,注釋僅僅是為了閱讀之用,只會出現在源程序中,不會出現在目標程序中。3.1.3匯編語言中常用符號約定

為了便于指令的描述,對指令中常用的符號有如下約定:

(1)?Rn:表示當前工作寄存器中的R0~R7,其中n=0~7。當前工作寄存器組由程序狀態(tài)寄存器PSW的RS1和RS0位決定。

(2)?Ri:表示當前工作寄存器中的R0~R1,其中i取值為0或1。

(3)?direct:表示對內部單元直接尋址的8位地址,可以是內部RAM區(qū)的某一單元或某一特殊功能寄存器的地址,變化范圍為00H~FFH。。

(4)?@:表示間接尋址寄存器及地址寄存器的前綴。

(5)?DPTR:表示16位數據指針。

(6)?#data:表示指令中的8位立即數,其中#表示立即數,data表示8位立即數,取值范圍為00H~FFH。

(7)?#data16:表示指令中的16位立即數,取值范圍為0000H~FFFFH。

(8)?PC:表示16位程序計數器。

(9)?addr11:表示短轉移的11位地址,用于2KB范圍內尋址。

(10)?addr16:表示長轉移的16位地址,用于64KB范圍內尋址。

(11)?rel:表示相對轉移的地址偏移量。

(12)?bit:表示位尋址區(qū)的直接尋址位。

(13)?(x):表示x地址單元中的內容。

(14)?((x)):表示將x地址單元中的內容作為地址的單元中的內容。

(15)?←:表示操作數據的流向,將箭頭后面的內容傳送到前面。

(16)?/:表示取反操作。指令尋找操作數地址的方式稱為尋址方式。指令中的操作數分為目的操作數和源操作數,兩者參與計算機操作時都有自己的尋址方式,為了方便描述,對有目的操作數和源操作數的雙操作數指令,無特別說明情況下,其尋址方式是指源操作數的尋址方式。指令系統的尋址方式越多,指令功能就越強,當然同時指令的結構就越復雜。

MCS-51指令系統共有7種尋址方式,包括立即數尋址、直接尋址、寄存器尋址、寄存器間接尋址、變址尋址、相對尋址和位尋址等。3.2單片機的指令尋址方式3.2.1立即數尋址

立即數尋址是指將操作數直接寫在指令中,不需要從其他的存儲空間中尋找和獲取。指令中立即數可以是8位或者16位,并且要在其前冠以“#”前綴,以區(qū)別于地址,主要用于賦值操作。該尋址方式只能用于源操作數。

例如:MOVA,#00H;(A)←00H

該指令執(zhí)行的操作是將立即數00H送到累加器A中,該指令就是立即數尋址。#00H中的“H”是說明該立即數是以十六進制表示的,實際編程時也可以用其他進制來表示。該指令的執(zhí)行過程如圖3.1所示。圖3.1立即數尋址示意圖3.2.2直接尋址

直接尋址是指把存放操作數的內存單元的地址直接寫在指令中。在MCS-51單片機中,可以直接尋址的存儲器主要有內部RAM區(qū)和特殊功能寄存器(SFR)區(qū)。

例如:MOVA,50H;(A)←(50H)

該指令執(zhí)行的操作是將內部RAM中地址為50H單元的內容傳送到累加器A中,其操作數50H就是存放數據的單元地址。所以該指令是直接尋址。若50H單元中的內容是55H,則該指令執(zhí)行后A的內容就是55H。該指令的執(zhí)行過程如圖3.2所示。圖3.2直接尋址示意圖3.2.3寄存器尋址

寄存器尋址是指將操作數存放于寄存器中。寄存器包括工作寄存器R0~R7、累加器A、通用寄存器B、地址寄存器DPTR和C。

例如:MOVA,R0;(A)←(R0)

該指令執(zhí)行的操作是把R0寄存器中的數據傳送到A累加器中,其操作數存放在R0中,所以尋址方式為寄存器尋址。若R0寄存器單元中的內容是55H,則該指令執(zhí)行后A的內容就是55H。該指令的執(zhí)行過程如圖3.3所示。圖3.3寄存器尋址示意圖特別要強調的是,像P0、P1、PSW等特殊寄存器沒有寄存器尋址方式,只有直接尋址方式。比如,MOVA,P0這個指令表面上是寄存器尋址,但在指令集中對應的機器碼是不存在的,實際上執(zhí)行的是MOVA,80H(P0地址)這條指令,是直接尋址。3.2.4寄存器間接尋址

寄存器間接尋址是指將存放操作數的內部RAM地址放在特定的寄存器中,指令中只給出該寄存器。MCS-51指令系統中,能用于寄存器間接尋址的寄存器有R0、R1和DPTR,稱為寄存器間接尋址寄存器,作為寄存器間接尋址時寄存器間接尋址寄存器的前面必須加上符號“@”。圖3.4寄存器間址尋址示意圖3.2.5變址尋址

變址尋址是指將基址寄存器與變址寄存器的內容相加,結果作為操作數的地址。DPTR或PC是基址寄存器,累加器A是變址寄存器。該類尋址方式主要用于查表操作。

例如:MOVCA,@A+DPTR;(A)←((A+DPTR))

該指令執(zhí)行的操作是將累加器A的內容和基址寄存器DPTR的內容相加,相加結果作為操作數存放的地址(地址在程序存儲器中),再將操作數取出來送到累加器A中。若累加器A的內容為80H,DPTR的內容為1000H,程序存儲器單元1080H中的內容是55H,則執(zhí)行該指令后A的內容就是55H,執(zhí)行過程如圖3.5所示。圖3.5變址尋址示意圖3.2.6相對尋址

相對尋址是指程序計數器(PC)以當前值(以下不做特別提示時,均指的是當前值)為基準與指令中的相對偏移量(rel)相加,形成新的有效轉移地址(下一個取指令的地址)。該類尋址方式主要用于跳轉指令。

要說明的是,該指令執(zhí)行時的程序計數器當前值是該指令的首地址加上該指令的字節(jié)數;rel是一個帶符號的8位二進制數,以補碼表示,能表示的范圍是-128~+127個字節(jié)單元之間,若為負數表示從當前地址向上轉移(小于當前地址),反之就向下轉移(大于當前地址)。例如:SJMP08H;(PC)←(PC)+08H

該指令執(zhí)行的操作是將PC當前的值與08H相加,結果再送回PC中,成為下一條將要執(zhí)行指令的地址。指令SJMP08H是雙字節(jié)指令,其機器碼為80H、08H,若存放在1000H處,當執(zhí)行到該指令時,先從1000H和1001H單元取出指令,PC自動變?yōu)?002H(PC當前值);再把PC的內容與操作數08H相加,形成目標地址100AH,再送回PC,使得程序跳轉到100AH單元繼續(xù)執(zhí)行,執(zhí)行過程如圖3.6所示。圖3.6相對尋址示意圖3.2.7位尋址

位尋址是指令中直接給出位地址,可以對有位地址的存儲單元進行操作。MCS-51單片機中,操作數不僅可以按字節(jié)為單位進行操作,也可以按位進行操作。當我們將某一位作為操作數時,這個操作數的地址稱為位地址。位尋址區(qū)包括在內部RAM中的兩個特殊區(qū)域:一是內部RAM的位尋址區(qū),字節(jié)地址范圍是20H~2FH,共16個RAM單元,對應的位地址為00H~7FH,共128位;二是特殊功能寄存器SFR中有11個寄存器可以位尋址,可以參見第2章中有關位地址的內容。

MCS-51單片機指令系統功能豐富,共有111條指令,操作碼有255個,助記符有48個。可按指令長度、執(zhí)行時間和功能等方法對指令進行分類。

(1)按指令長度分為單字節(jié)指令(49條)、雙字節(jié)指令(46條)和三字節(jié)指令(16條)。

(2)按執(zhí)行周期分為單周期指令(64條)、雙周期指令(45條)和四周期指令(2條)。

(3)按功能分為數據傳送指令(29條)、算術運算指令(24條)、邏輯運算指令(24條)、位操作指令(17條)和程序控制指令(17條)。

下面按功能分類分別介紹每條指令的格式、功能、用途等。3.3單片機的指令系統3.3.1數據傳送類指令

數據傳送類指令是MCS-51單片機匯編語言程序設計中使用最頻繁的指令,包括內部數據傳送、外部數據傳送、查表、數據交換、堆棧操作5種類型共29條指令,使用了8種助記符,分別為MOV、MOVX、MOVC、XCH、XCHD、SWAP、PUSH和POP。數據傳送類指令有立即尋址、直接尋址、寄存器尋址、寄存器間接尋址和變址尋址5種尋址方式。數據傳送操作是指把數據從源地址傳送到目的地址,源地址內容不變,而目的操作數修改為源操作數,或者源操作數與目的操作數互換,即源操作數變成目的操作數,目的操作數變成源操作數,以保存目的操作數不被丟失。

數據傳送類指令不影響標志位(對狀態(tài)寄存器PSW操作除外),即不影響進位標志位Cy、半進位標志位AC和溢出標志位OV,但不包括檢驗累加器A奇偶性的標志位P。數據傳送操作是指把數據從源地址傳送到目的地址,源地址內容不變,而目的操作數修改為源操作數,或者源操作數與目的操作數互換,即源操作數變成目的操作數,目的操作數變成源操作數,以保存目的操作數不被丟失。

數據傳送類指令不影響標志位(對狀態(tài)寄存器PSW操作除外),即不影響進位標志位Cy、半進位標志位AC和溢出標志位OV,但不包括檢驗累加器A奇偶性的標志位P。

1.內部數據傳送指令

內部數據傳送指令共16條,主要用于內部RAM與寄存器之間的數據傳送。指令基本格式為

MOV[目的操作數][,源操作數]

1)以累加器A為目的地址的傳送指令

此類指令共有四條,如表3.1所示。表3.1以累加器A為目的地址的傳送指令以上指令說明了在傳送類指令中,A可以接收從Rn、direct和#data傳送的數據;結果影響程序狀態(tài)字寄存器中的P標志;n=0~7,i=1~2。

例3.1

已知執(zhí)行指令前A、R0、內部RAM30H和50H中的內容分別是20H、30H、80H、10H,請說明每條指令的功能,并指出執(zhí)行后相應單元內容和奇偶標志位P的變化。

①?MOVA,R0

②?MOVA,50H

③?MOVA,@R0

④?MOVA,#55H

解:①該指令完成了(A)←(R0);執(zhí)行后(A)=30H,P=0,其他的內容不變。

②該指令完成了(A)←(50H);執(zhí)行后(A)=10H,P=1,其他的內容不變。

③該指令完成了(A)←((R0));執(zhí)行后(A)=80H,P=1,其他的內容不變。

④該指令完成了(A)←#55H;執(zhí)行后(A)=55H,P=0,其他的內容不變。

2)以Rn為目的地址的傳送指令

該類指令共有三條,如表3.2所示。表3.2以Rn為目的地址的傳送指令以上指令說明了在傳送類指令中,Rn可以接收從A、direct和#data傳送的數據。

例3.2

設目前的工作寄存器使用的是0組,R0中的內容是55H,R2中的內容是50H,請判斷用下面的程序是否可以完成將R2中的內容傳送給R0。

①?MOVR0,R2

②?MOVR0,02H

③MOVA,R2

MOVR0,A

解:①由于在指令中沒有直接Rn和Rn傳送數據的指令,故該指令不存在,所以不能完成。

②由已知得R2在RAM中地址是02H,所以該指令是將R2作為內部RAM,用直接尋址方式完成了數據的傳送。

③指令通過A作為數據的中轉,先將(A)←(R2),再將(R0)←(A),完成了數據傳送。

通過上面的例子可以看出,同樣的功能可以用多個不同的程序實現。

3)以直接地址為目的地址的傳送指令

該類指令共有五條,如表3.3所示。表3.3以直接地址為目的地址的傳送指令以上指令說明了在傳送類指令中,direct可以接收從A、Rn、direct和#data傳送的數據,還要注意的是,MOVdirect2,direct1指令中,匯編指令的目的操作數、源操作數與機器碼存放的次序不一致。

例3.3

設內部RAM30H和40H中的內容分別是18H和88H,請將40H的內容傳給30H,分別用匯編語言和機器語言編寫該程序段,該段程序的起始地址為2000H。

解:匯編語言程序段為

2000HMOV30H,40H;(30H)

(40H)

機器語言程序段為

2000H85

2001H40

2002H30

從該程序段可以看出,匯編語言指令的目的操作數在前,源操作數在后,而機器語言剛好相反。

4)以寄存器間接地址為目的地址的傳送指令

該類指令共有三條,如表3.4所示。表3.4以寄存器間接地址為目的地址的傳送指令以上指令說明了在傳送類指令中,@Ri可以接收從A、direct和#data傳送的數據,不能接收來自Rn的數據。

例3.4

已知R0、R1、內部RAM50H和51H的內容分別為50H、51H、30H和31H,請指出下列指令執(zhí)行后各目的操作數內容相應的變化。

①?MOVA,51H

MOV@R0,A

②?MOV@R1,#55H

解:①?MOVA,51H執(zhí)行后(A)=(51H)=31H;MOV@R0,A執(zhí)行后((R0))=(50H)=(A)=31H。

②?MOV@R1,#88H執(zhí)行后((R1))=(51H)=88H。

5)?16位數據傳送指令

該類指令有一條,如表3.5所示。表3.516位數據傳送指令這是唯一的一條16位立即數傳遞指令,可將一個16位的立即數送入數據指針DPTR中去,其中高8位送入DPH,低8位送入DPL。

2.外部數據傳送指令

外部數據傳送指令共四條,如表3.6所示,主要用于累加器A與外部數據存儲器或I/O端口之間的數據傳送。在此我們就可以看出內、外部RAM的區(qū)別了,內部RAM間可以直接進行數據的傳遞,而外部RAM間則不行。指令基本格式為

MOVX[目的操作數][,源操作數]表3.6外部數據傳送指令

以上指令說明CPU與外部的數據傳送只能通過累加器A來實現;累加器A與外部RAM之間傳送數據時只能用間接尋址方式,間接尋址寄存器為DPTR、R0和R1;DPTR能尋址的范圍是64KB,而R0和R1只能尋址256B以內。以上傳送指令的結果通常影響程序狀態(tài)字寄存器的P標志。

例3.5

把外部數據存儲器2000H單元中的數據傳送到外部數據存儲器2100H單元中。

解:MOVDPTR,#2000H

MOVXA,@DPTR;先將2000H單元的內容傳送到

累加器A中

MOVDPTR,#2100H

MOVX@DPTR,A;再將累加器A中的內容傳送

到2100H單元中

3.交換類指令

交換類指令共五條,主要用于累加器A與內部數據存儲單元之間的數據傳送。與其他的數據傳送指令不同的是數據傳送是雙向的,即目的操作數和源操作數在指令執(zhí)行時互為目的地址和源地址,指令執(zhí)行后各自的操作數都修改為另一方的操作數,兩個操作數都會保留而不會因數據的傳送而丟失。

1)字節(jié)交換指令

字節(jié)交換指令共三條,如表3.7所示。表3.7字節(jié)交換指令以上指令執(zhí)行后兩個操作數相互交換;A可以和內部RAM中的任一個單元交換內容;指令結果影響程序狀態(tài)字寄存器的P標志。

2)半字節(jié)交換指令

半字節(jié)交換指令有一條,如表3.8所示。表3.8半字節(jié)交換指令該指令執(zhí)行后兩個操作數的低4位相互交換,高4位不變;A可以通過Ri間址和內部RAM中的任一個單元交換內容;指令結果影響程序狀態(tài)字寄存器的P標志。

3)累加器A中高4位和低4位交換

累加器A中高4位和低4位交換的指令有一條,如表3.9所示。表3.9累加器A中高4位和低4位交換指令

該指令執(zhí)行后A的低4位和高4位相互交換;指令結果不影響程序狀態(tài)字寄存器的標志位。

例3.6

設內部數據存儲區(qū)2AH、2BH單元中連續(xù)存放有四個BCD碼:a3a2和a1a0,試編寫一程序把這四個BCD碼倒序排序,即a0a1和a2a3。

解:MOV

A,2AH;將2AH(a3a2)傳送到A(a3a2)中

SWAPA ;將A(a3a2)中的高4位與低4位交換

為A(a2a3)

XCHA,2BH;將A(a2a3)與2BH(a1a0)的內容互換

SWAPA ;將A(a1a0)中的高4位與低4位交換

為A(a0a1)

MOV 2AH,A;累加器A(a0a1)的內容傳送到

2AH(a0a1)單元

4.查表指令

本組指令有兩條,如表3.10所示,用于將程序存儲器ROM中的數送入A中。本組指令之所以被稱為查表指令,是因為常用來查一個已做好在ROM中的表格。指令基本格式為

MOVC[目的操作數][,源操作數]表3.10查表指令

以上指令結果影響程序狀態(tài)字寄存器的P標志。

例3.7

有一個數在R0中,要求用查表的方法確定它的平方值(此數的取值范圍是0~5),試編寫一程序段完成之。

解:設將0~5的平方值依次放在程序存儲器1000H為首的存儲單元中。

MOVDPTR,#1000H;將1000H送入DPTR

MOVA,R0;將R0中的數送入A

MOVCA,@A+DPTR;取出該數的平方值

ORG1000H

TABLE:DB0,1,4,9,16,25

5.堆棧操作指令

本組指令有兩條,如表3.11所示。第一條為壓入指令,就是將direct中的內容送入堆棧中;第二條為彈出指令,就是將堆棧中的內容送回到direct中。表3.11堆棧操作指令堆棧是用戶自己設定的內部RAM中的一塊專用存儲區(qū),使用時一定先設堆棧指針,堆棧指針缺省為SP=07H;堆棧遵循先進后出的原則安排數據;堆棧操作必須是字節(jié)操作,且只能直接尋址;堆棧通常用于臨時保護數據及子程序調用時保護現場/恢復現場,一般情況下,PUSH/POP指令都是成對使用的;結果不影響程序狀態(tài)字寄存器的標志位。

例3.8

說明下面程序段的功能。

MOV SP,#50H

MOV A, #10H

MOV B, #20

PUSH ACC

POP B

解:MOVSP,#50H;(SP)←50H,即內部RAM50H

是棧底

MOVA,#10H;(A)←10H

MOVB,#20;(B)←20(十進制數)

PUSHACC;(SP)←(SP)+1,(SP)=51H,

((SP))←(ACC)

POPB;(B)←((SP)),(SP)←(SP)-1,

(SP)=50H3.3.2算術運算類指令

算術運算類指令主要針對8位無符號數,也可用于帶符號數運算,包括加、減、乘、除、加1、減1運算指令共24條;使用了8種助記符,分別為ADD、ADDC、SUBB、DA、INC、DEC、MUL和DIV。

算術運算類指令通常會影響PSW的進位標志位Cy、半進位標志位AC和溢出標志位OV,奇偶性標志位P取決于累加器A的奇偶性;有立即尋址、直接尋址、寄存器尋址和寄存器間接尋址四種尋址方式。

1.加法指令

1)普通加法指令(4條)

普通加法指令即不帶進位的加法指令,有四條,如表3.12所示。表3.12普通加法指令本組指令將A中的值與源操作數所指內容相加,最終結果存在A中;結果均影響程序狀態(tài)字寄存器的Cy、OV、AC和P標志。無符號數運算時,關注的主要是Cy,若Cy=0表示運算結果小于等于255,若Cy=1則表示產生了進位;帶符號數運算時,關注的主要是OV,若OV=0表示運算正確,結果在-128~+127之間,若OV=1則表示運算出錯,超出了-128~+127的范圍,要對結果進行處理。

例3.9

分析下面的指令執(zhí)行后,狀態(tài)字寄存器的Cy、AC、OV和P位的狀態(tài)。

MOVA,#10H

ADD?A,#0F2H

解:指令執(zhí)行過程可用下式表示。表3.13帶進位加法指令

ADDC與ADD的區(qū)別是加了進位位Cy,將A中的值和其后面的值以及進位位Cy中的值相加,最終結果存在A中,常用于多字節(jié)數加法運算中。

例3.10

設X0、Y0存放在R1和R0中,X1、Y1存放在R3和R2中,試編寫計算雙字節(jié)加法R1R0+R3R2,并將結果存在R5R4中的程序。

解:單片機指令系統中只提供了8位的加法運算指令,兩個16位數(雙字節(jié))相加可分為兩步進行,第一步先對低8位相加,第二步再對高8位相加。MOV A,R0

ADD A,R2 ;求低8位的和并送入A中,進位送Cy

MOV R4,A ;低8位的和存入R4

MOV A,R1

ADDCA,R3 ;求高8位與低8位進位Cy的和并送入A

中,進位送Cy

MOV R5,A ;低8位的和存入R5

2.減法指令

減法指令共有四條,如表3.14所示。

本組指令將A中的值減去源操作數所指內容以及進位位C中的值,最終結果存在A中。與加法指令相比較,減法指令中沒有不帶借位的減法指令,所以在做不帶借位的減法指令(在做第一次相減時)時,應將Cy清零。表3.14減法指令

例3.11

設12H和34H分別存放在R1和R0中,試編寫計算R0減R1,并將結果存在60H中的程序。

解:MOVA,R0;被減數送A

CLRC;進位標志位Cy清零,為不帶借位的

減法做準備

SUBBA,R1;與R1的內容相減

MOV60H,A;結果存放在60H

3.?BCD碼調整指令

BCD碼調整指令有一條,如表3.15所示。表3.15BCD碼調整指令助記符格式機器碼(H)指令說明狀態(tài)字寄存器DAAD4BCD碼加法調整指令CyACOV在進行BCD碼加法運算時,跟在ADD和ADDC指令之后(不適用于減法),用于對累加器A中剛進行的兩個BCD碼的加法結果進行十進制調整:

(1)當累加器A中的低4位數出現了非BCD碼(大于9的二進制數:1010~1111)或低4位產生進位(AC=1)時,則應在低4位加6調整,以產生低4位正確的BCD碼結果;

(2)當累加器A中的高4位數出現了非BCD碼(大于9的二進制數:1010~1111)或高4位產生進位(Cy=1)時,則應在高4位加6調整,以產生高4位正確的BCD碼結果。

例3.12

若(A)=01011000B,表示的BCD碼為58,(R3)=01100110B,表示的BCD碼為66,(Cy)=0。試編寫這兩個壓縮的BCD碼相加的程序,結果的百位送入51H、十位和個位送入50H。

解:由已知編寫程序段為

ADDA,R3;求R3與A的和,結果送入A中

DAA;由于是壓縮BCD碼加法,因此進行BCD碼調

MOV50H,A;調整后的十位和個位送入(50H)=24H

MOVA,#00H ;A清零

ADDCA,#00H ;進位標志位的內容作為百位送入A

MOV51H,A ;百位送入(50H)=01H表3.16加1減1指令本組指令是將指令中所指出的操作數內容加1;最后一條指令是對于16位數據指針寄存器加DPTR1操作。在指令中如果操作數是I/O(P1~P3)端口,則其先從端口將數據“讀”出,加1后,再將修改了的數據寫回到端口中,一條指令相當于進行了“讀—修改—寫”三個操作,稱這類指令為“讀—修改—寫”指令。

5.減1指令

減1指令共有四條,如表3.17所示。表3.17減1指令本組指令是將指令中所指出的操作數內容減1;應注意沒有對16位數據指針寄存器DPTR減1操作的指令;在指令中如果操作數是I/O(P1~P3)端口,則屬于“讀—修改—寫”指令。

6.乘、除法指令

乘、除法指令共有二條,如表3.18所示。表3.18乘、除法指令乘法結果影響程序狀態(tài)字寄存器的Cy:積超過0FFH,置1,否則置0;Cy總是清0。除法結果也同樣影響程序狀態(tài)字寄存器的OV:除數為0,置1,否則為0;Cy總是清0。當除數為0時結果不能確定。3.3.3邏輯運算類指令

邏輯運算類指令主要用于對兩個操作數按位進行邏輯操作,結果送到A或直接尋址單元,包括與、或、異或、移位、取反、清零等共24條指令;使用了9種助記符,分別為ANL、ORL、XRL、CLR、CPL、RLA、RLCA、RRA和RRCA。

這類指令一般不影響標志位,有立即尋址、直接尋址、寄存器尋址和寄存器間接尋址四種尋址方式。

1.邏輯運算指令

1)邏輯與指令

邏輯與指令共有六條,如表3.19所示。表3.19邏輯與指令表3.20邏輯或指令表3.21邏輯異或指令表3.22累加器A清0和取反指令

2.循環(huán)移位指令

循環(huán)移位指令共有四條,如表3.22所示。表3.22循環(huán)移位指令本組指令的功能是將A的內容按指令指定的方向(左或右)和方式(帶或不帶進位)進行簡單的移位,每執(zhí)行一次指令移動1位。執(zhí)行帶進位的循環(huán)移指令之前,必須給Cy置位或清0,這樣才能確定移位以后的結果。對RLC、RRC指令,在Cy=0時執(zhí)行一次RLC相當于乘以2,執(zhí)行一次RRC相當于除以2。

例3.16

若(A)=10001000B=88D,試用右移指令編寫將A除以4的程序段。

解:因為執(zhí)行一次RRC相當于除以2,因此執(zhí)行2次即可完成除4的功能。

CLRC;由于Cy要參與操作,所以將其清零,為除2做

準備

RRCA;第一次帶進位右移:(A)=01000100B=44D

CLRC;為除以2做準備

RRCA;第二次帶進位右移:(A)=00100010B=22D3.3.4位操作類指令

位操作指令的操作數是“位”,其取值只能是0或1,故又稱之為布爾變量操作指令。位操作指令的操作對象是片內RAM的位尋址區(qū)(即20H~2FH)和特殊功能寄存器中的11個可位尋址的寄存器(如表2.8所示)。片內RAM的20H~2FH共16個單元128位(如表2.7所示),我們?yōu)檫@128位的每個位均定義一個名稱,為00H~7FH。位操作指令主要完成的操作是以位為對象的數據傳送、邏輯運算和控制轉移等。共17條指令;使用了11種助記符,即MOV、SETB、JB、JNB、JBC、JC、JNC、ANL、ORL、CLR和CPL;除了對進位位C操作的指令會對進位標志有影響外,其他不影響標志位。

這類指令的位地址有四種表達方式:

(1)直接(位)地址方式,如00H。

(2)點操作符號方式,如ACC.4,P2.3。

(3)位名稱方式,如RS0。

(4)用戶定義名方式:如用偽指令bit。

1.位傳送指令

位傳送指令有兩條,如表3.23所示。表3.23位傳送指令該位傳送指令必須與進位位C進行,不能在其他兩個位之間傳送。若位地址bit是I/O端口,則為“讀—修改—寫”指令。

例3.17

編寫程序,將P1.1中的狀態(tài)送到P1.0中。

解:由于位傳送指令不能在兩個位之間直接傳送,必須通過進位位C中轉,因而有:

MOV

C,

P1.1;將P1.1中的狀態(tài)送到Cy

MOV

P1.0,

C;將Cy中的狀態(tài)送到P1.0

2.位置位和位清0指令

位置位和位清0指令共有四條,如表3.24所示。表3.24位置位和位清0指令該組指令是位清0、置位指令。若位地址bit是I/O端口,則為“讀—修改—寫”指令。

例3.18

如圖3.7所示電路,P1.1端口接了一個發(fā)光二極管,編寫點亮或熄滅該二極管的程序段。圖3.7例3.18電路

解:由圖3.7所示可知,當P1.1是低電平時點亮,高電平時熄滅,所以程序為

CLR

P1.1;(P1.1)←0,點亮二極管

SETB

P1.1;(P1.1)←1,熄滅二極管

3.位運算指令

位運算指令共有六條,如表3.25所示。表3.25位運算指令該組指令的結果通常影響程序狀態(tài)字寄存器的Cy標志。若位地址bit是I/O端口,則為“讀—修改—寫”指令。注意指令系統中沒有位異或指令,如需異或操作,可以用其他指令組合完成。

例3.19

設X、Y、Z為三個位地址,試完成(Z)=(X)(Y)運算的程序編程。

解:異或運算可分解為(Z)=(X)/(Y)+/(X)(Y),程序設計如下:

MOVC,X ;(Cy)←(X)

ANLC,/Y ;(Cy)←(X)/(Y)

MOVZ,C ;(Z)←(Cy)暫存(X)/(Y)的結果

MOVC,Y ;(Cy)←(Y)

ANLC,/X ;(Cy)←(X)/(Y)

ORLC,?Z ;(Cy)←(X)/(Y)+/(X)(Y)

MOVZ,C ;保存結果

4.位轉移指令

位轉移指令共有三條,如表3.26所示。

該組指令的結果不影響程序狀態(tài)字寄存器。JBC與JB指令的區(qū)別是,前者轉移后并把尋址位清0,后者只轉移而不清0尋址位。需要再次強調的是,PC的當前值是該指令的首地址加上該指令的字節(jié)數;rel是一個帶符號的8位二進制數,以補碼表示,能表示的范圍是-128(-80H)~127(7FH)個字節(jié)單元之間,若為負數表示從當前地址向上轉移(小于當前地址),反之就向下轉移(大于當前地址)。表3.26位轉移指令

例3.20

設下列指令的首地址是1000H,位20的內容為1,試簡述下列指令執(zhí)行中各有關操作數的變化情況。

(1)1000H

JB20,08H

(2)1000H

JB20,FDH

(3)1000H

JB20,FAH

解:(1)由已知得位20的內容為1,則該指令要跳轉到(PC)+rel的地址。由于該指令是3字節(jié)指令,因此執(zhí)行該指令時,PC的值已經是1003H,rel是08H(正值),所以有(PC)+rel=1003H+08H=100BH,即計算機下一條指令從100BH開始。

(2)由已知得位20的內容為1,則該指令要跳轉到(PC)+rel的地址。由于該指令是3字節(jié)指令,因此執(zhí)行該指令時,PC的值已經是1003H,rel是FDH(是-3),所以有(PC)+rel=1003H-03H=1000H,即計算機下一條指令從1000H開始。該指令執(zhí)行后實際又回到了原來的位置,所以如果位20的內容不變,則程序將一直在這里循環(huán)。

(3)由已知得位20的內容為1,則該指令要跳轉到(PC)+rel的地址。由于該指令是3字節(jié)指令,因此執(zhí)行該指令時,PC的值已經是1003H,rel是FAH(是-6),所以有(PC)+rel=1003H-06H=0FFDH,即計算機下一條指令從0FFDH開始。

5.判Cy標志指令

判斷Cy標志的指令有兩條,如表3.27所示。表3.27判Cy標志指令

例3.21

將JCrel指令用于例3.12中。

解:由已知編寫程序段如下:

ADDA,R3;求R3與A的和,結果送入A中

DAA;由于是壓縮BCD碼加法,因此進行BCD碼

調整

MOV50H,A;調整后的十位和個位送入(50H)=24H

JC PR1;若(Cy)=1,跳至PR1,百位送1;否則清0

MOV51H,#00H ;百位送入(50H)=00H

PR1:MOV51H,#01H ;百位送入(50H)=01H3.3.5控制轉移類指令

控制轉移類指令的本質是改變程序計數器PC的內容,從而改變程序的執(zhí)行方向??刂妻D移指令分為無條件轉移指令、條件轉移指令和調用、返回指令,指令豐富,共有17條。此類指令一般不影響PSW的狀態(tài)。

1.無條件轉移指令

1)長轉移指令

長轉移指令有一條,如表3.28所示。表3.28長轉移指令該指令可以轉移到64KB程序存儲器中的任意位置;為了編程和閱讀方便,在實際使用時,地址一般用標號表示。

例3.22

在上電復位后,程序要跳轉到用戶程序地址標號為START的入口程序。

解:在上電復位后,單片機的第一條指令從存儲器0000H單元開始執(zhí)行,由于0003H~0023H單元對應的是單片機各中斷源的中斷服務入口地址,一般情況下用戶的程序不允許占用,因此第一條指令一般都是跳轉指令。程序段如下

0000HLJMPSTART;(PC)←START(16位地址)

START:…

2)絕對轉移指令

絕對轉移指令有一條,如表3.29所示。表3.29絕對轉移指令該指令轉移范圍是2KB,是一條雙字節(jié)指令。其機器碼是由11位直接地址addr11~0和指令特有操作碼00001按下列分布組成的:第一個字節(jié)a10a9a800001,第二個字節(jié)a7a6a5a4a3a2a1a0。

該指令執(zhí)行后,程序轉移目的地址是由該指令的PC當前值(該指令在程序存儲器的首地址加該指令的字節(jié)數)的高5位與指令中提供的11位直接地址組成的,即

PC15PC14PC13PC12PC11a10a9a8a7a6a5a4a3a2a1a0由于11位地址的變化范圍是000H~7FFH,即2KB范圍,轉移目的地址高5位由PC當前值固定,因此程序可轉移的范圍只能是和PC當前值在同一2KB范圍之內。

例3.23

指令2020HAJMP0FFH執(zhí)行后PC的內容是什么?

解:該指令的首地址為2020H,執(zhí)行后PC的當前值為首地址2020H加2,即2022H,然后由2022H的高5位和11位直接地址0FFH組成新的PC值,即0010000011111111B,也即程序從20FFH開始執(zhí)行。

例3.24

指令2FFFHAJMP0FFH執(zhí)行后PC的內容是什么?

解:該指令的首地址為2FFFH,執(zhí)行后PC的當前值為首地址2FFFH加2,即3001H,然后由3001H的高5位和11位直接地址0FFH組成新的PC值,即0011000011111111B,也即程序從30FFH開始執(zhí)行。

以上兩個例子中,指令是相同的,但由于指令的首址不同導致執(zhí)行的結果是不一樣的。應掌握該指令的執(zhí)行過程。

3)相對轉移指令

相對轉移指令有一條,如表3.30所示。表3.30相對轉移指令該指令結果不影響程序狀態(tài)字寄存器,轉移范圍是以本指令的下一條指令為中心的-128~+127字節(jié)以內。在實際應用中,LJMP、AJMP和SJMP后面的addr16~0、addr11~0或rel常用標號來代替,不一定寫出它們的具體地址。

例3.25

指令2FFFHSJMP23H執(zhí)行后PC的內容是什么?

解:該指令的首地址為2FFFH,執(zhí)行后PC的當前值為首地址2FFFH加2,即3001H,然后由3001H加23H組成新的PC值,即(PC)=(PC)+2+23H=3024H開始執(zhí)行。

無條件轉移指令AJMP、LJMP和SJMP的不同點:

(1)構成不同,AJMP、LJMP后跟的是絕對地址,而SJMP后跟的是相對地址;

(2)指令長度不同,AJMP、SJMP是雙字節(jié)指令,LJMP是3字節(jié)指令;

(3)跳轉的范圍不同,SJMP為-128~127B,AJMP為2KB,而LJMP是64KB,且原則上可以替代前兩條指令。

4)間接尋址的無條件轉移指令

間接尋址的無條件轉移指令有一條,如表3.31所示。表3.31間接尋址的無條件轉移指令該指令可代替眾多的判別跳轉指令,又稱為散轉指令,多用于多分支程序結構中。該指令的功能是把累加器中8位無符號數與數據指針DPTR中的16位數相加(模216),結果作為下條指令地址送入PC;不改變累加器和數據指針內容,也不影響標志位。利用這條指令能實現程序的散轉。

例3.26

累加器A中存放待處理命令,編號為0~7,試編寫程序,完成功能:根據A內命令編號轉向相應的命令處理程序。

2.條件轉移指令

1)累加器A判0指令

累加器A判0指令有兩條,如表3.32所示。表3.32累加器A判0指令表3.33比較轉移指令該組指令的功能是將兩個操作數相比較,能判斷兩數是否相等或哪個數大:如果兩者相等,就順序執(zhí)行;如果不相等,就轉移,若目的操作數大于源操作數,則Cy=0,否則Cy=1。

例3.28

累加器A中存放待處理數據:如果為大于或等于3CH(十進制的60),就向內部RAM30H加1,否則就向內部RAM31H加1。試編寫該數據處理程序段。表3.34減1非零轉移指令

3.調用和返回指令

指令系統中一般都有調用子程序的指令和從子程序返回主程序的指令。在程序設計中,經常會執(zhí)行功能完全相同的一段程序,為了減少程序編寫和調試的工作量,可使這段程序作為公用,即子程序。由主程序用調用子程序指令進入子程序,執(zhí)行子程序后,在子程序的末尾安排一條返回主程序的指令再返回主程序,完成一次子程序調用。

1)絕對調用指令

絕對調用指令有一條,如表3.35所示。表3.35絕對調用指令該指令調用范圍與AJMP指令相同:被調用子程序入口地址必須與調用指令的下一條指令(PC當前值)的第一字節(jié)在相同的2KB存儲區(qū)之內。執(zhí)行的過程為:將PC當前值壓入堆棧;將指令中的11位地址送入PC的低11位,得到了調用的子程序入口地址。

例3.30

若(SP)=60H,標號LOOP的值為0123H,子程序SUB位于0345H,試敘述下列指令執(zhí)行過程,并說明該指令能否完成對SUB子程序的調用。如果子程序SUB位于0B45H,能否完成對SUB子程序的調用?

LOOP:ACALLSUB

SUB:…

解:先求得(PC)+2=0125H;再壓入堆棧,即(SP)+1=60H+1=61H中壓入25H,(SP)+1=61H+1=62H中壓入01H;接著完成了保護斷點,(SP)=62H。子程序SUB位于0345H,指令中只提供了SUB的低11位地址,即addr10~0=01101000101,并送給PC10~0,PC值的高5位內容不變,即PC15~11為00000,所以這時形成的PC值為

(PC)=0000001101000101B=0345H

說明該指令已完成對SUB子程序的調用。若子程序SUB位于0B45H,則其他過程與上面相同,不同之處是:子程序SUB位于0B45H,指令中只提供了SUB的低11位地址,即addr10~0=01101000101,并送給PC10~0,PC值的高5位內容不變,即PC15~PC11為00000,所以這時形成的PC值為

(PC)=0000001101000101B=0345H

該地址不是我們所希望的地址0B45H,故該指令不能完成對SUB子程序的調用。

從上例中我們就可以看出:使用ACALL指令時一定要使PC當前值與子程序入口地址的高5位地址相同,即處于同一個2KB范圍內,否則將無法完成指令的調用。

2)長調用指令

長調用指令有一條,如表3.36所示。表3.36長調用指令該指令調用范圍與LJMP指令相同,可以轉移到64KB程序存儲器中的任意位置。執(zhí)行的過程為:將PC當前值壓入堆棧;將指令中的16位地址送入PC,得到調用的子程序的入口地址。

3)返回指令

返回指令共有兩條,如表3.37所示。表3.37返回指令該組指令用于子程序最后一條指令,實現由子程序返回主程序的功能。不同的是,RET指令的執(zhí)行過程是:堆棧棧頂內容(2字節(jié),調用時保存的當前PC值)彈出給PC,實現返回,只能用在子程序中;RETI指令除了具有RET指令的功能外,還要對中斷優(yōu)先級狀態(tài)觸發(fā)器清零,只能用在中斷子程序中。

4)空操作

空操作指令有一條,如表3.38所示。表3.38空操作指令該指令為單字節(jié)指令,占用一個機器周期,在該周期內CPU不作任何操作;不影響程序狀態(tài)字寄存器;經常用作短時間的延時。程序設計是單片機應用系統設計的重要組成部分,其主要目的就是為了解決某一個問題,將指令有序地組合在一起,用計算機所能接受的語言把解決問題的步驟描述出來,也就是編制計算機的程序。常用的MCS-51程序設計語言有MBASIC51、C51等高級語言和匯編語言。目前匯編語言是單片機應用系統設計常用的程序設計語言之一,特別是對于初學者,掌握匯編語言及編程方法有助于對單片機硬件的學習和計算機系統設計。3.4匯編語言程序設計3.4.1常用偽指令

單片機匯編語言程序設計中,除了使用指令系統規(guī)定的指令外,還要用到一些偽指令。偽指令又稱指示性指令,具有和指令類似的形式。匯編時偽指令并不產生可執(zhí)行的目標代碼,只是對匯編過程進行某種控制或提供某些匯編信息。不同版本的匯編語言,偽指令的符號和含義可能有所不同,但基本的用法是相似的。下面對常用的偽指令作一簡單介紹。

1.定位偽指令ORG

格式:[標號:]ORG16位地址

功能:規(guī)定程序塊或數據塊存放的起始位置是該16位地址。在一個匯編語言源程序中允許使用多條定位偽指令,規(guī)定不同程序段的起始位置,地址應該從小到大,地址不允許重疊。

例如:ORG1000H

MOVA,#00H

表示指令MOVA,#00H存放于1000H開始的單元。

2.匯編結束偽指令END

格式:[標號:]END

功能:匯編語言源程序結束標志。在該指令后的指令,匯編程序都不予以處理。在整個匯編語言程序中只能有一個匯編結束偽指令,且放在程序的末尾處。

3.定義字節(jié)偽指令DB

格式:[標號:]DB項或項表

功能:項或項表可以是一個字節(jié)數據,或用逗號分開的字符串,或以引號括起來的字符串。它表示將項或項表中的數據從左到右依次存放在指定地址單元。例如:ORG1000H

TAB:DB

2BH,0A0H,′A′,′BCD′

表示TAB的地址為1000H,從該地址開始的單元依次存放數據2BH、A0H、41H(字母A的ASCII碼)、42H(字母B的ASCII碼)、43H(字母C的ASCII碼)、44H(字母D的ASCII碼),即相當于對這些單元賦值:

(1000H)=2BH

(1001H)=A0H

(1002H)=41H

(1003H)=42H

(1004H)=43H

(1005H)=44H

4.定義字偽指令DW

格式:[標號:]DW項或項表

功能:與DB類似,但DW定義的項或項表字為兩個字節(jié)。存放數據時高位在前,低位在后。

例如:ORG1000H

DATA:DW3000H,90H

表示從1000H單元開始的地方存放數據30H、00H、00H、90H(90H以字的形式表示為0090H),即:

(1000H)=30H

(1001H)=00H

(1002H)=00H

(1003H)=90H

5.定義空間偽指令DS

格式:[標號:]DS表達式

功能:從指定的地址開始,保留多少個存儲單元作為備用的空間,空間大小由表達式決定。

例如:ORG1000H

DLY:DS32H

TAB:DB22H

表示從1000H開始的地方預留32(1000H~101FH)個存儲字節(jié)空間,22H存放在1020H單元。

6.等值偽指令EQU

格式:標號:EQU項

功能:將項的值賦給本語句的標號。項可以是常數、地址標號或者表達式。通常該語句放在源程序的開頭部分;在同一程序中對某個標號賦值后,其值將不能再改變。

例如:DLY:EQU3200H

TAB:EQUDLY

第一條表示DLY地址的值是3200H,第二條表示TAB地址與DLY地址的值相等。

7.位地址賦值偽指令BIT

格式:標號:BIT位地址

功能:將位地址賦給本語句的標號。經賦值的標號可以代替指令中的位,即在程序中,標號和該位地址是等價的。

例如:DLY1:BIT31H

DLY2:BIT32H

經過上述定義后,在編程時,可以把DLY1和DLY2當作位地址31H和32H。3.4.2程序設計方法

要設計一個好的程序,僅知道指令系統是遠遠不夠的,還需掌握一些編程的基本方法、程序的基本結構及設計步驟等常識,這樣才能在編程實踐中不斷地完善自己的設計能力。

1.程序設計步驟

用匯編語言編寫一個程序的過程可分為以下幾個步驟:

(1)針對所要研究的對象進行分析,明確要解決的問題。

(2)根據實際問題的要求和指令系統的特點,決定所采用的計算公式和計算方法,即算法。算法是進行程序設計的依據,它決定了程序的正確性和程序的質量。

(3)制定程序流程圖(稱為程序框圖)。根據所選的算法,制定出運算步驟和順序,把運算過程畫成程序流程圖。編寫較復雜的程序時,畫出程序流程圖是十分必要的(初學者往往不重視),它可以使程序清晰,結構合理。按照基本結構編寫程序,也便于編程和調試。

(4)確定數據格式,分配單片機的資源。分配內存工作區(qū)及為有關端口地址分配內存工作區(qū)時,要根據程序區(qū)、數據區(qū)、暫存區(qū)、堆棧區(qū)等預計所占空間大小,對片內、外存儲區(qū)進行合理分配并確定每個區(qū)域的首地址,便于編程使用。

(5)編制匯編源程序。

(6)程序測試。利用單片機仿真器結合單片機目標系統,對程序進行測試,排除程序中的錯誤,直到正確為止。

(7)程序優(yōu)化。程序優(yōu)化就是指優(yōu)化程序結構,縮短程序長度,加快運算速度和節(jié)省數據存儲單元。在程序設計中,經常使用循環(huán)程序和子程序的形式來縮短程序,通過改進算法和正確使用指令來節(jié)省工作單元和減少程序執(zhí)行的時間。

2.程序的基本結構

程序的基本結構有順序程序結構、分支程序結構和循環(huán)程序結構三種。

1)順序程序結構

按指令的排列順序一條條地執(zhí)行,直到全部指令執(zhí)行完畢為止的程序結構稱為順序程序結構。順序程序結構在編程中是最簡單、最基本的程序結構,不管多么復雜的程序,總是由若干順序程序段所組成的。在順序程序結構中沒有判斷、沒有分支。

順序程序結構如圖3.8所示,程序A或程序B表示計算機的某種操作,箭頭表示程序指令的方向。圖3.8順序程序結構

2)分支程序結構

根據程序要求改變程序執(zhí)行順序,即程序的流向有兩個或兩個以上的出口,根據指定的條件選擇程序流向的程序結構稱為分支程序結構。實際問題一般都是比較復雜的,單使用順序結構程序是無法解決的,因為實際問題總是伴隨有邏輯判斷或條件選擇,要求計算機能根據給定的條件進行判斷,選擇不同的處理路徑。編程的關鍵是如何確定供判斷或選擇的條件以及選擇合理的分支指令。

單分支程序結構如圖3.9所示,單分支結構的特點是:一個入口,兩個出口。該結構中有一個判斷框,根據條件C是否成立選擇執(zhí)行分支程序A或分支程序B。圖3.9單分支程序結構

3)循環(huán)程序結構

在一定的條件成立或不成立時,反復執(zhí)行一段程序,稱為循環(huán)程序結構。這種結構可大大縮短程序代碼,減少占用的程序空間,優(yōu)化程序結構,提高程序質量。

如圖3.10所示,循環(huán)程序結構由兩部分組成,分別為循環(huán)體A和循環(huán)條件C。循環(huán)體A即要重復執(zhí)行的程序段;循環(huán)條件C即決定是執(zhí)行循環(huán)體或者結束循環(huán)的判斷條件。循環(huán)程序結構又分為當型循環(huán)程序結構和直到型循環(huán)程序結構兩種形式,如圖3-10(a)、(b)所示。當型循環(huán)程序結構先判斷循環(huán)條件C,條件成立則執(zhí)行循環(huán)體A,否則退出循環(huán);直到型循環(huán)程序結構先執(zhí)行循環(huán)體A,再判斷循環(huán)條件C,不成立則再執(zhí)行循環(huán)體A,否則退出循環(huán)。圖3.10循環(huán)程序結構(a)當型循環(huán)程序結構;(b)直到型循環(huán)程序結構

3.單片機應用系統程序的組成

一個完整的單片機應用系統程序由主程序和其他功能子程序組成,如圖3.11所示。圖中,單片機復位后PC為0000H,也就是程序從程序存儲器的0000H開始執(zhí)行。由于MCS-51單片機程序存儲器的0003H、000BH、0013H、001BH、0023H分別是外部中斷0、定時器0、外部中斷1、定時器1、串行口的中斷入口地址,因此主程序開始的地址一般安排在0030H之后的程序存儲器中。一般在程序存儲器的0000H處放一條無條件轉移指令(AJMP、LJMP、SJMP),以便轉到主程序的開始處。由于每個中斷入口地址之間只有8個字節(jié)的空間,一般無法完成中斷服務程序的編程需要,因而在相應的中斷入口地址處也放一條無條件轉移指令。圖3.11單片機應用系統程序總體結構

1)主程序

主程序是程序的主干,是必不可少的部分。在進入主程序后一般來講首先要對所用的可編程的硬件資源進行初始化,如內部的中斷、定時器、串行口、有些I/O口(外部擴展可編程芯片等)以及主要的RAM單元等;然后由主程序按順序調用各功能模塊(子程序),如顯示、鍵盤、采樣等。

2)子程序

子程序一般都是具有一定功能的程序模塊。它可被主程序或其他子程序調用。根據系統的具體要求,將一些功能模塊編制成子程序,如顯示模塊、鍵盤模塊、延時模塊、通信模塊、數據采集模塊、數據處理模塊、數據輸出模塊等。

在實際的單片機應用系統軟件設計中,為了程序結構更加清晰,易于設計、便于修改,增強程序可讀性,基本上都要使用子程序結構。子程序作為一個具有獨立功能的程序段,編程時需注意以下幾點:

(1)子程序的第一條指令必須有標號:明確子程序入口地址。

(2)要有簡明扼要的子程序說明部分:說明該子程序的功能和所用到的資源,如寄存器、內部RAM等。

(3)注意保護現場和恢復現場:如果在子程序中所用到的資源與其他程序發(fā)生了沖突,則需要進行保護。

(4)有較強的通用性和可浮動性;盡可能避免使用具體的內存單元和絕對轉移地址等,以方便程序修改。

(5)以返回指令RET結束子程序。

程序調試時在主程序中可逐個調用各功能模塊進行調試,直到每一個模塊調試完成后,再進行聯調。

3)中斷服務程序

中斷服務程序也是具有某種功能的程序模塊,通常執(zhí)行一些較為特殊的功能,如外部特殊事件(掉電、故障、通信等)的處理。它與子程序的區(qū)別是進入方式不同:子程序的進入方式是由主程序或其他子程序進行調用,即在程序中何時運行子程序是固定的;而中斷服務程序則不同,中斷服務程序的進入是根據中斷產生,再由CPU根據實際的情況決定的,它是一個隨機的事件,可在程序運行的任何時刻產生。編程時需注意事項與子程序的類似,只是要強調的是,中斷服務程序執(zhí)行完后,由中斷返回指令RETI返回到斷點處;由于中斷處理的是重要的事件,因此設計中斷服務程序時要簡短,運行時間不宜過長;對于不使用的中斷最好將其關閉(有關的控制寄存器),從抗干擾的方面考慮,簡單的方法是可將不用的中斷入口地址寫一條跳轉到0000H的指令,在系統出現故障時,進行軟件恢復系統。3.4.3匯編語言程序設計舉例

至此我們已基本具備了編寫匯編程序的知識,下面我們通過一些常用程序的分析,進一步學習匯編程序的設計。

1.數據傳送程序設計

數據傳送程序是程序設計中常見的程序,MCS-51系列單片機存儲器結構的特點之一是存在著四種物理存儲空間,即片內RAM、片外RAM、片內ROM和片外ROM。不同的物理存儲空間之間的數

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論