在單片機應用系統設計中,過去主要采用匯編語言開發程序。匯編語言編寫的程序對單片機硬件操作很方便,編寫的程序代碼短,效率高,但系統設計的周期長,可讀性和可移植性都很差。C語言程序開發是近年來單片機系統開發應用所采用的主要開發方式之一,C語言功能豐富、表達能力強、使用靈活方便、開發周期短、可讀性強、可移植性好。但是,采用C語言編程還是存在著如對硬件沒有匯編方便、效率沒有匯編高、編寫延時程序精確度不高等缺點,因而現在單片機系統開發中經常用到C語言與匯編語言混合編程技術。混合編程技術可以把C語言和匯編語言的優點結合起來,編寫出性能優良的程序。單片機混合編程技術通常是,程序的框架或主體部分用C語言編寫,對那些使用頻率高、要求執行效率高、延時精確的部分用匯編語言編寫,這樣既保證了整個程序的可讀性,又保證了單片機應用系統的性能。
1、混合編程的基本方式
C語言與匯編語言混合編程通常有兩種基本方法:在C語言中嵌入匯編程序和在C語言中調用匯編程序。
1.1 在C51 中嵌入匯編程序
在C51中嵌入匯編程序主要用于實現延時或中斷處理,以便生成精練的代碼,減少運行時間。嵌入式匯編通常用在當匯編函數不大,且內部沒有復雜的跳轉的時候。在單片機C語言程序中嵌入匯編程序是通過C51中的預處理指令#pragmaasm/endasm語句實現,格式如下:
#pragmaASM
;匯編程序代碼
#pragmaENDASM
通過#pragmaasm和#pragmaendasm告訴C51編譯器它們之間的語句行不用編譯成匯編程序代碼。
1.2 在C51 中調用匯編程序
在C51中調用匯編程序的方法應用較多,C模塊與匯編模塊的接口較簡單,分別用C51與A51對源程序進行編譯,然后用L51將obj文件連接即可,關鍵問題在于C函數與匯編函數之間的參數傳遞和得到正確返回值,以保證模塊間的數據交換。
2、C51 與匯編程序的參數傳遞
在C51中嵌入匯編程序或調用匯編程序,其參數傳遞的過程是不一樣的。
2.1在C51 中嵌入匯編程序的參數傳遞
對于在C語言程序中通過#pragmaasm和#pragmaendasm嵌入的匯編程序,C51編譯器在編譯時只是將當中的匯編程序不編譯,而不做其他任何處理,因此不存在函數調用時的參數傳遞和返回值問題。如果要在C程序中和匯編程序中實現數據傳遞,可以通過變量或特殊功能寄存器來實現,例如,在C程序的變量定義部分定義Z變量,在C語言程序和匯編程序中共同訪問Z變量,這樣,C語言程序可以通過Z變量把參數傳遞給匯編程序,匯編程序可以通過Z變量把參數返回給C語言程序。
2.2在C51 中調用匯編程序的參數傳遞
在C51中調用匯編程序是通過函數調用的形式來實現的。由于C51程序函數有明確的參數和返回值約定,因此在C51中調用匯編程序進行參數傳遞時都必須嚴格遵守C51函數的參數和返回值相關約定。
在C51中調用匯編程序進行參數傳遞關鍵在于要弄清C51函數的參數傳遞規則。在C51中調用匯編程序進行參數傳遞的方式有兩種:一種是通過寄存器傳遞參數;一種是通過固定存儲區傳遞。
2.2.1通過寄存器傳遞參數。
FranklinC51規定調用函數最多可通過51單片機的工作寄存器傳遞3個參數,余下的通過固定存儲區傳遞??梢杂谩癗OREGPARMS”命令取消用寄存器傳遞參數,如果用寄存器傳遞參數取消或參數太多,參數通過固定存儲區傳遞。用寄存器傳遞參數的函數,在生成代碼時被Cx51編譯器在函數名前加上一個下劃線“_”的前綴,在固定存儲區傳遞參數的函數則沒有下劃線。不同的參數用到的寄存器不一樣,不同的數據類型用到的寄存器也不同。通過寄存器傳遞的參數如表1所示。
表1中,int型和long型數據傳遞時高位數據在低位寄存器中,低位數據在高位寄存器中;float型數據滿足32位的IEEE格式,指數和符號位在R7中;通用指針存儲類型在R3中,高位在R2中。函數參數傳遞舉例情況如表2所示。
2.2.2通過固定存儲區傳遞。
用固定存儲區傳遞參數給匯編程序,參數段首地址用段名“function-nAMEBYTE”和“function-name?BIT”保存,function-name為函數的名稱,其中“,?function-name?BIT”保存位參數段首地址,“function-nameBYTE”保存別的參數段首地址,即使通過寄存器傳遞參數,參數也將在這些段中分配空間,參數按聲明的先后在每個段中順序保存。
用做參數傳遞的固定存儲區可在內部數據區或外部數據區,這由存儲模式決定。Small模式的參數段用內部數據區,Compact和Large模式用外部數據區。
2.2.3函數返回值。
函數返回值通常用寄存器傳遞,表3列出了可能的返回值和所用的寄存器。
3、C51 中嵌入匯編程序的實現方法
通常,在C51程序中嵌入匯編程序的處理方法如下:
第一步,在C文件中以如下方式嵌入匯編程序。
#pragmaASM
;匯編程序
#pragmaENDASM
第二步,在keilC51軟件的Project窗口右鍵單擊嵌入匯編程序的C文件,選擇“Optionsfor?”,點擊右邊的“GenerateAssemblerSRCFile”和“AssembleSRCFile”,使檢查框由灰色變成黑色(有效)狀態。
第三步,根據選擇的編譯模式,把相應的庫文件(如Small模式時,是Keil\C51\Lib\C51S。Lib)加入工程中,該文件必須作為工程的最后文件。
庫文件與編譯模式的關系如下:
C51S.LIB - 沒有浮點運算的Small model
C51C.LIB - 沒有浮點運算的Compact model
C51L.LIB - 沒有浮點運算的Large model
C51FPS.LIB - 帶浮點運算的Small model
C51FPC.LIB - 帶浮點運算的Compact model
C51FPL.LIB - 帶浮點運算的Large model
第四步,編譯,即可生成目標代碼。
keil軟件中c編程如何制作一個庫函數并在其他地方隨意調用?
在項目的Output設置中選擇輸出lib而不是可執行目標文件。
4、C51 中調用匯編程序的實現方法
為了能夠在C語言中調用匯編程序,要求匯編程序的編寫必須符合C語言的相關命名規則。
C51程序在調用匯編程序時,除了前面參數傳遞的相關規則外,函數及其相關段也需要滿足一定的規則。
一個C51源程序模塊被編譯后,其中的每一個函數以“?PR?函數名?模塊名”為名的命名規則被分配到一個獨立的CODE段。例如,如果模塊“FUNC51”內包含一個名為“func”的函數,則其CODE段的名字是“?PR?FUNC?FUNC51”,如果函數中還包含有data和bit對象的局部變量,編譯器將按“?函數名?BYTE和?函數名?BIT”命令規則建立一個data和bit段,它們代表所要傳遞參數的起始位置,其偏移值為零。段內代碼與數據定義也遵循一定的規則。這些段是公開的,它們的地址可被其他模塊訪問。另外,這些段被編譯器賦予“OVERLAYABLE”標志,其可被L51連接P定位器做覆蓋分析。
下面是一個簡單的C51程序編譯時形成的匯編程序。
C語言源程序如下:
#defineucharunsignedchar
ucharmax(ucharx,uchary){
ucharz;
z=(x>=y)?x:y;
return(z);
}
匯編后形成的SRC文件(只須擴展名改為.a51就變成匯編程序)如下:
NAMEA1;定義模塊名稱
?PR?_max?A1SEGMENTCODE;定義程序代碼
PUBLIC_max;定義公共符號
;#defineucharunsignedchar
;ucharmax(ucharx,uchary)
RSEG?PR?_max?A1;程序代碼段
_max:;起始地址
USING0
;SOURCELINE#2
;??Variable’y?041’assignedtoRegister’R5’??
;??Variable’x?040’assignedtoRegister’R7’??
;{
;SOURCELINE#3
;ucharz;
;z=(x>=y)?x:y;
;SOURCELINE#5
MOVA,R7;R7中為第二個字節參數
CLRC
SUBBA,R5;R5中為第一個字節參數
JC?C0001
SJMP?C0002
?C0001:
MOVR7,AR5;R7中為返回值
?C0002:
;??Variable’z?042’assignedtoRegister’R7’??
;return(z);
;SOURCELINE#6
;SOURCELINE#7
;}
?C0003:
RET
;ENDOF-max
END
可以看出,要編寫為C51調用的匯編程序,除了參數必須按前面規定的寄存器或存儲器傳送外,程序格式也有相應的規則。這些規則比較繁瑣,在實際處理中往往按下面方式處理:
第一步,先用C語言程序編寫出程序框架,如文件名為a1.c(注意參數)。
第二步,在keilC51的Project窗口中用右鍵單擊該C語言文件,在右鍵菜單中選擇“Optionsfor?”,點擊右邊的“GenerateAssemblerSRCFile”和“AssembleSRCFile”,使檢查框由灰色變成黑色(有效)狀態。
第三步,根據選擇的編譯模式,把相應的庫文件(如Small模式時,是Keil\C51\Lib\C51S.Lib)加入工程中,該文件必須作為工程的最后文件。庫文件與編譯模式的關系如前面所述。
第四步,編譯后將會產生一個SRC的文件,將這個文件擴展名改為ASM。這樣就形成了可供C51程序調用的匯編程序。隨后可在該文件的代碼段中加入所需指令代碼。
第五步,將該匯編程序與調用它的主程序一起加到工程文件中,這時工程文件中不再需要原來的C語言文件和庫文件,主程序只需要在程序開始處用EXTERN對所調用的匯編程序中的函數作聲明,主程序中可調用匯編程序中的函數。
-
單片機
+關注
關注
6042文章
44617瀏覽量
637485 -
寄存器
+關注
關注
31文章
5363瀏覽量
120926 -
C語言
+關注
關注
180文章
7614瀏覽量
137409
原文標題:51單片機asm與C混合編程
文章出處:【微信號:changxuemcu,微信公眾號:暢學單片機】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論