




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第6章程序設計6.1匯編語言的語法6.2匯編語言程序的基本結構6.3匯編語言程序設計舉例6.4C語言程序設計6.5C語言和匯編語言混合編程本章小結
6.1匯編語言的語法
6.1.1數制、數據類型與參數
m'nSP的匯編器將十進制作為默認數制,十六進制數可用符號“0x”或“$”作為前綴,或用符號“H”作為后綴。各種數制的后綴請參見表6.1。
m'nSP是16位微處理器,其基本數據類型字符占16位地址空間。表6.2列出了所有的數據類型信息。6.1.2算邏操作符及其優先次序
表6.3列出了m'nSP指令的各種算邏操作符以及它們各自的作用。這些運算符有一定的優先次序,如表6.4所示,同一行運算符具有相同的優先次序。
6.2匯編語言程序的基本結構
6.2.1順序程序結構
順序程序是程序設計中的基本模塊。順序程序沒有分支,從第一條指令開始依次執行每一條指令,直到最后一條指令執行完畢。其特點是由數據傳送指令和算術邏輯運算指令構成,雖然順序程序比較簡單,但也能完成一定的功能,而且往往是構成復雜程序的基礎。順序程序結構的基本形式如圖6.1所示。圖6.1順序程序結構的基本形式6.2.2分支程序結構
一般情況下,程序按順序方式執行,有時也需要機器能根據不同情況,執行不同的程序或程序段,這就要求所編制的程序具有判斷、選擇的能力,即需要分支結構的程序。其特點是程序中含有轉移指令,轉移指令分為無條件轉移指令和有條件轉移指令,因此分支程序也可分為無條件分支轉移程序和有條件分支轉移程序。有條件分支轉移程序按結構類型來分,又分為雙分支轉移結構和多分支轉移結構。分支程序結構的基本形式如圖6.2所示。圖6.2分支程序結構的基本形式實現分支的兩種基本方法如下。
(1)利用比較/測試等邏輯運算指令結合轉移指令實現分支。
【例6.1】階躍函數。
這是一個典型的雙分支結構,輸入值大于等于0時則返回1,輸入值小于0時返回0。
(2)利用表實現分支。
最簡單的分支轉移程序設計,一般采用逐次比較法,就是把所有不同的情況一個一個的進行比較,發現符合條件的就轉向對應的處理程序段。6.2.3循環程序結構
在一些單片機應用系統中,往往同一組操作要重復許多次,這種強制CPU多次重復執行一段指令的基本程序結構稱為循環程序結構。特點是程序中含有可以反復執行的程序段,該程序段通常稱為循環體。圖6.3循環程序的結構形式常用的兩種循環控制方法如下。
(1)用計數法控制循環。
計數控制方法只有在循環次數已知的情況下才適用。對循環次數未知的問題,不能用循環次數來控制,往往需要根據某種條件來判斷是否應該終止循環。
(2)按條件控制循環。
有些情況下,計數次數無法事先確定,但循環次數與問題中的某些條件有關,這些條件可以檢測到,這時采用條件控制循環。6.2.4子程序結構
一般來說子程序的結構包括三個部分:
(1)子程序的定義聲明和開始標號部分;
(2)子程序的實體內容部分,表明程序將進行怎樣的操作;
(3)子程序的結束標號部分。
子程序結構定義如下:
子程序名.PROC
程序體
RETF
.ENDP
1.子程序調用過程
程序的調用包括主程序調用子程序,子程序調用子程序等。程序調用是通過調用指令“CALL……”來實現的。程序執行的過程中,當遇到調用子程序指令,CPU便會將下一條指令的地址壓入堆棧暫時保護起來,然后轉到被調用的子程序入口去執行子程序,當執行到RETF時返回,CPU又將堆棧中的返回地址彈出送到PC,繼續執行原來的程序。其過程如圖6.4所示。圖6.4子程序調用過程
1)通過寄存器傳遞參數
寄存器傳遞參數,是最常用的一種參數傳遞方式。常用到的傳遞參數的寄存器有4個,分別為R1~R4;在程序調用的過程中,寄存器中的值也會被帶到被調用的子程序中供子程序使用。以主程序調用子程序為例:在調用子程序前,R1~R4這4個寄存器中可能暫存一些值,發生調用子程序以后,這些值仍被帶到相應的子程序中繼續參加子程序的運算,子程序運算結束后返回主程序,這些寄存器的新值也會被帶到主程序中繼續參加主程序的運算。
【例6.3】求32位有符號數的絕對值。
這是一個利用寄存器傳遞變量的例子。
2)通過變量傳遞參數
通過變量進行的參數傳遞,主要是通過全局型變量實現的。在匯編中,一個變量名,就代表了一個實際的寄存器的物理地址,可以直接對物理地址進行賦值和讀取,但這種方法會帶來很多麻煩。用變量名去代表一個實際的物理地址,就涉及到某部分匯編代碼是否認識該變量名的問題。
3)通過堆棧傳遞參數
在C函數與匯編函數的相互調用過程中,主要通過堆棧來傳遞參數,而在函數返回時,則采用寄存器來傳遞返回值。主程序把要傳遞的參數壓入堆棧,然后調用子程序。子程序從堆棧中尋找需要的參數進行處理。當子程序返回后,主程序需要進行彈棧處理,以恢復參數壓入堆棧前的堆棧狀態。
2.子程序嵌套與遞歸
1)子程序的嵌套
子程序嵌套就是指子程序調用子程序。其中嵌套的層數稱為嵌套深度。
2)遞歸子程序
遞歸調用是指子程序調用自身子程序。
進行遞歸調用時需注意的是,一個遞歸程序必須有一個能夠退出遞歸調用的測試語句。也就是說,遞歸調用是有條件的,滿足了條件后,才可以進行遞歸調用;如果無條件地進行遞歸調用,那么會使堆棧空間溢出,導致嚴重的錯誤。
【例6.4】計算N!(N≥0)的程序。
編程分析:求N!本身是一個子程序,由于N!是N和(N-1)!的乘積,所以求(N-1)!必須遞歸調用求N!的子程序。
程序說明:r1存的是階乘數N,r2存的是N!的值。該程序可以計算的最大階乘數N等于8,當N大于8時,會溢出,這時R2被賦值為0xFFFF。6.2.5中斷服務子程序結構
在單片機中,中斷技術主要用于實時控制。所謂實時控制,就是要求單片機能及時地響應被控對象提出的分析、計算和控制等請求,使被控對象保持在最佳工作狀態,以達到預定的控制效果。由于這些控制參量的請求都是隨機發出的,而且要求單片機必須作出快速響應并及時處理,因此,必須應用中斷方式來處理。圖6.5中斷服務程序的一般流程中斷服務程序以函數的形式存在,每個中斷向量對應一個特定名稱的中斷服務函數。對于匯編語言編寫的程序,中斷服務函數名稱分別為:“_BREAK”,“_FIQ”,“_IRQ0”,“_IRQ1”,…,“_IRQ7”,且要定位在?.TETX段。例如,IRQ2中斷服務程序應寫成如下形式:
.PUBLIC_IRQ2
.TEXT
_IRQ2:
… //中斷服務程序內容
Reti對于C語言編寫的程序,中斷服務函數應分別命名為:“BREAK()”,“FIQ()”,“IRQ0()”,“IRQ1()”,…,“IRQ7()”;且要聲明為形如“voidIRQ0(void)__attribute__
((ISR));”的形式。例如,FIQ中斷服務程序應寫成:
voidFIQ(void)__attribute__((ISR));
voidFIQ(void)
{
… //中斷服務程序內容
}中斷函數匯編程序基本結構:
【例6.5】IOA低四位IOA0~IOA3控制LED1~LED4四個發光二極管,IOA4~IOA7控制LED5~LED8四個發光二極管。每響應一次IRQ5_2Hz中斷,IOA0~IOA3四個端口輸出電平翻轉,控制LED1~LED4四個發光二極管的亮滅狀態。每響應一次IRQ5_4?Hz中斷,IOA4~IOA7四個端口輸出電平翻轉,控制LED5~LED8四個發光二極管的亮滅狀態變化。
6.3匯編語言程序設計舉例
6.3.1查表程序設計
在單片機應用程序的設計中,表的用途十分廣泛:求平方值、立方值需要使用平方值表和立方值表,程序實現分支要用到跳轉表等;大量供各種運算、查詢等用的機器執行的任務,一組組的結果,一系列有關聯的數據等,都需要使用表來存儲或處理。由于SPCE061A具有寄存器間接尋址和變址尋址方式,所以查表的基本方法有如下兩種。
方法一:寄存器間接尋址方式。
Rn=表首地址
Rn+=偏移地址
Rd=[Rn]
//取得表中的數據
方法二:變址尋址方式。
BP=表首地址
Rn=[BP+偏移地址] //取得表中的數據
【例6.6】查8位十六進制數平方表。
【例6.7】查表跳轉程序。6.3.2排序程序設計
【例6.8】冒泡排序(相鄰數比較互換的排序方法,類似水中氣泡上浮)。
算法分析:算法的基本思想是采用兩兩比較的方法:先拿an與an-1比,若an>an-1,則不交換,反之則交換;然后用an-1與an-2相比,按同樣原則決定是否交換,這樣一直比下去,最后用a2與a1相比,也按同樣原則決定是否交換。6.3.3碼制轉換程序設計
碼制的轉換可以用三種方法實現:
(1)算術邏輯運算;
(2)查表法;
(3)硬件電路。
1.二進制碼到BCD碼的轉換
BCD碼有兩種形式:一種是1個字節放1位BCD碼,它適用于顯示或輸出;一種是壓縮的BCD碼,即1個字節放兩位BCD碼,可以節省存儲單元。
【例6.9】二進制碼到BCD碼的轉換的子程序。
2.BCD碼到二進制碼的轉換
算法說明:設BCD碼為a,b,c,d,則相應的二進制數為1000a+100b+10c+d=((a×10+b)×10+c)×10+d,將各位BCD碼分離出之后,即可根據此式轉換為二進制數。
【例6.10】BCD碼到二進制碼的轉換子程序。
說明:R1作為入口參數時,存的是BCD碼,其中b0~b3存個位數的BCD碼,b4~b7存十位數的BCD碼,b8~b11存百位數的BCD碼,b12~b15存千位數的BCD碼。R1作為出口參數時,存的是轉換后的二進制數。
3.二進制碼與ASCII碼之間的轉換
【例6.11】
二進制碼到ASCII碼的轉換。
算法說明:對于小于等于9的4位二進制數加0x30得到相應ASCII碼,對于大于9的4位二進制數加0x37得到相應ASCII代碼。6.3.4I/O接口應用程序設計
輸入和輸出設備是計算機系統的重要組成部分。程序、數據和各種現場采集到的信息要通過輸入裝置輸入至計算機,計算結果或各種控制信息要輸出到各種輸出設備,以便顯示、打印和實現各種控制操作。因此,CPU與輸入/輸出設備之間的信息交換也是計算機系統中非常重要和十分頻繁的操作。
1.用SPCE061A控制發光二極管的亮滅
發光二極管在平時日常生活中是很常見的,同時在單片機的產品開發中也是最基本的硬件器件。
【例6.12】通過IOA口輸出的數據控制8個發光二極管的點亮與熄滅。IOA的低8位IOA0~IOA7分別依次接8個發光二極管。程序的主循環當中,輸出到IOA口低8位的數據每次輸出顯示后要加1;輸出顯示的數據可用變量保存,也可在程序運行當中通過讀取P_IOA_Buffer
(0x7001)寄存器得到上次輸出數值。
【例6.13】按鍵點亮發光二極管。
采用SPCE061A實現以下功能:IOA[7:0]外接8個按鍵,IOB[7:0]外接8個LED,當IOA口有鍵按下時在IOB對應位的LED顯示。
硬件原理如圖6.6所示。圖6.6按鍵顯示電路原理圖
2.SPCE061A控制數碼管輸出顯示內容
數碼管在工程中的應用極其廣泛,尤其在儀器儀表中的應用更多,比如萬用表、轉速表等。圖6.7數碼管的共陰和共陽接法
【例6.14】I/O端口控制6個數碼管循環顯示數字“0~9”。
要實現每個數碼管分別顯示不同數字的效果,例如,要顯示“123456”,則需要不斷地快速刷新數碼管的顯示狀態,即先使第一個數碼管顯示數字“1”,其他數碼管熄滅,然后熄滅第一個數碼管,第二個數碼管顯示數字“2”,以此類推。這樣,利用人眼的視覺殘留效應,就產生了“123456”同時顯示出來的效果。
3.鍵盤輸入應用
上面我們介紹了兩種最常見和最基礎的輸出器件:發光二極管和數碼管,這里我們介紹最常用的輸入器件——按鍵。按鍵是用來輸入各種開關量的器件,鍵盤是由若干個按鍵組成的開關矩陣,它是最簡單的單片機輸入設備。通過鍵盤輸入數據和命令,實現簡單的人機對話。
【例6.15】在數碼管上顯示按鍵的值,按第一個鍵顯示“1”,按第二個鍵顯示“2”,…,按第8個鍵顯示“8”。
6.4C語言程序設計
6.4.1m‘nSP嵌入式C語言(兩種C語言程序設計風格)
是否具有對高級語言HLL(HighLevelLanguage)的支持已成為衡量微控制器性能的標準之一。顯然,在HLL平臺上要比在匯編級上編程具有諸多優勢:代碼清晰易讀、易維護,易形成模塊化,便于重復使用從而增加代碼的開發效率。
SPCE061A單片機C語言編程設置端口的操作是通過指針來實現的。μ'nSPIDE集成開發環境編譯器所認可的指針是16位的。比如要設置IOA口為同相低電平輸出口時,可以通過下面幾句去實現:
如果不喜歡使用SPCE061.H,也不想包含SPCE061.LIB,也可以像下面這樣寫程序:6.4.2I/O接口的C語言程序設計
【例6.16】實現IOB0~IOB15端口的狀態隨著IOA0端口輸入電平的不同而變化,當IOA0端口輸入高電平時,IOB0~IOB15端口輸出高電平;當IOA0端口輸入低電平時,IOB0~IOB15端口輸出低電平。
【例6.17】I/O端口控制發光二極管亮滅。
通過SPCE061A的1位I/O端口(本例中使用IOA15端口)經一個限流電阻后接一個發光二極管至地,IOA15端口循環輸出高低電平,從而控制發光二極管循環亮滅。
【例6.18】按鍵點亮發光二極管。采用SPCE061A實現以下功能:IOA[7:0]外接8個按鍵,IOB[7:0]外接8個LED,當IOA口有鍵按下時在IOB對應位的LED顯示。
【例6.19】I/O端口控制數碼管循環顯示數字“0~9”,兩位數碼管同時循環顯示數字“0”~“9”。
6.5C語言和匯編語言混合編程
6.5.1C語言在線匯編
為了使C語言程序具有更高的效率和更多的功能,需在C語言程序里嵌入用匯編語言編寫的子程序。一方面是為提高子程序的執行速度和效率;另一方面,可解決某些用C語言程序無法實現的機器語言操作。而C語言代碼與匯編語言代碼的接口是任何C編譯器毋庸置疑需要解決的問題。
1.GCC在線匯編指令格式
采用GCC規定的在線匯編指令格式進行指令的輸入,是GCC實現將m‘nSP匯編指令嵌入C函數中的方法。GCC在線匯編指令格式規定如下:
asm(“匯編指令模板”:輸出參數:輸入參數:clobbers參數);
若無clobber參數,則在線匯編指令格式可簡化為:
asm(“匯編指令模板”:輸出參數:輸入參數);
1)匯編指令模板
模板是在線匯編指令中的主要成分,GCC據此可在當前位置產生匯編指令輸出。
例如,下面一條在線匯編指令:
asm(“%0+=%1”:“+r”(foo):“r”(bar));
此處,“%0+=%1”就是模板。其中,操作數“%0”、“%1”作為一種形式參數,分別由第一個冒號后面實際的輸出、輸入參數取代。帶百分號的數字表示的是第一個冒號后參數的序號。如下例:
asm(“%0=%1+%2”:“=r”(foo):“r”(bar),“i”(10));
“%0”由參數foo取代,“%1”由參數bar取代,而“%2”則由數值10取代。
在匯編輸出中,一個匯編指令模板里可以掛接多條匯編指令。其方法是用換行符“\n”來結束每一條指令,并用Tab鍵符“\t”將同一模板產生在匯編輸出中的各條指令在換行顯示時縮進到同一列,以使匯編指令顯示清晰。如下例:
asm(“%0+=%1\n\t%0+=%1”:“+r”(foo):“r”(bar));
2)操作數
在線匯編指令格式中,第一冒號后的參數為輸出操作數,第二冒號后的參數為輸入操作數,第三冒號后跟著的則是clobber操作數。在各類操作數中,引號里的字符代表的是其存儲類型約束符;括弧里面的字符串表示的是實際操作數。
3)操作數約束符
約束符的作用在于指示GCC使用在匯編指令模板中的操作數的存儲類型。表6.7列出了一些約束符和它們分別代表的操作數不同的存儲類型,也列出了用在操作數約束符之前的兩個約束符前綴。
2.利用嵌入式匯編實現對端口寄存器的操作
在C的嵌入式匯編中,當使用端口寄存器名稱時,需要在C文件中加入匯編的包含文件,如下所示:
asm(“.includehardware.inc”);
之后,在編程中就可以使用端口寄存器的名稱,而不必使用端口的實際地址。
1)寫端口寄存器
現舉例說明:要設定PortA端口為輸出端口,需要對P_IOA_Dir賦值0xffff。在C中有一個int型的變量i,傳送到P_IOA_Dir中,則嵌入匯編的實現方式如下:如果需要對端口寄存器直接賦值一個立即數(比如對P_IOA_Dir賦值0x1234),那么內嵌式匯編為:
2)讀端口寄存器
對端口寄存器進行讀操作的方法,與寫類似,下面以P_IOA_Dir為例,進行說明。
如果要實現把端口的寄存器P_IOA_Dir的值讀出并保存在C中的一個int變量j里,那么可以通過下面的方法來實現。
3)利用GCC編程舉例
【例6.20】用GCC編程實現對A口的初始化:設定A口為同向輸出高電平。上面代碼通過GCC編譯后的代碼為:
【例6.21】用GCC編程實現對B口的初始化:設定B口為具有上拉電阻的輸入。上面一段代碼通過GCC編譯后的匯編代碼為:
【例6.22】通過上述兩段代碼,使得SPCE061A的B口為輸入,A口為輸出,如果我們要實現把B口得到的數據從A口輸出,這樣的GCC編程需要在C中先建立個int型的中間變量,通過這個中間變量,寫出兩個GCC的代碼來實現。通過GCC后的代碼如下所示。這里將看不到temp的影子,GCC會進行優化處理。
R1=[P_IOB_Data]
[P_IOA_Buffer]=R16.5.2C語言和匯編語言的相互調用
1.程序調用協議
由于C編譯器產生的所有標號都以下劃線(?_?)為前綴,而C程序在調用匯編語言程序時要求匯編語言程序名也以下劃線(?_?)為前綴。調用協議包括以下一些相關要素:
(1)調用子程序間的參數傳遞;
(2)子程序返回值;
(3)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 以舊換新銀行活動方案
- 價值準則活動方案
- 企業全員閱讀活動方案
- 企業借款活動方案
- 企業公司社團活動方案
- 企業創新之星活動方案
- 企業號直播店鋪活動方案
- 企業團委雷鋒活動方案
- 企業奠基活動方案
- 企業家投資交流活動方案
- 湖南炎德·英才大聯考長郡中學2025屆模擬試卷(一)語文+答案
- 2025年南通市通大全過程工程咨詢有限公司招聘筆試參考題庫附帶答案詳解
- 2025云南紅河州紅投智慧物流限公司社會招聘筆試和易考易錯模擬試題(共500題)試卷后附參考答案
- 糖尿病腎病患者護理
- 房屋安全鑒定服務投標方案
- 委托代建代管合同協議
- 開發面試題及答案大全
- 2025年4月版安全法律法規標準文件清單
- 防雷應急預案演練方案
- 無障礙欄桿施工方案范本
- 銀行保安筆試題及答案
評論
0/150
提交評論