摘 要: 本文介紹了C語(yǔ)言與匯編語(yǔ)言混合編程的規(guī)則,討論了混合編程的一般方法。并在此基礎(chǔ)上從工程實(shí)際的角度對(duì)混合編程的幾項(xiàng)關(guān)鍵問(wèn)題作了深入的論述。
現(xiàn)代電子設(shè)備中,對(duì)數(shù)據(jù)處理能力的要求日益提高。數(shù)字信號(hào)處理器(DSP),由于具有先進(jìn)的體系結(jié)構(gòu),強(qiáng)大的信號(hào)處理能力而得到了蓬勃的發(fā)展。在本文所涉及的容錯(cuò)供配電系統(tǒng)設(shè)計(jì)中,采用了TMS320LF240xA系列,它作為TI公司DSP向傳統(tǒng)的單片機(jī)領(lǐng)域滲透的產(chǎn)品,在控制領(lǐng)域得到了廣泛的應(yīng)用。
DSP具有的優(yōu)勢(shì)允許它面向更加復(fù)雜的應(yīng)用。對(duì)于這類系統(tǒng),采用嵌入式實(shí)時(shí)操作系統(tǒng)極大的改善了系統(tǒng)的設(shè)計(jì)與運(yùn)行。它不僅提高了開發(fā)的效率,而且提高了程序運(yùn)行的效率,穩(wěn)定性,以及擴(kuò)展性等。本設(shè)計(jì)中采用了mC/OS-II v2.62。該內(nèi)核已歷經(jīng)近十年的應(yīng)用與改進(jìn),在實(shí)用性與可*性方面得到了廣泛的好評(píng)。開放源代碼的優(yōu)勢(shì)也使它尤其適合設(shè)計(jì)中自檢測(cè),以及故障診斷與定位的要求。
C與匯編混合編程的一般規(guī)則
C語(yǔ)言的mC/OS-II內(nèi)核帶來(lái)了編程方式選擇的問(wèn)題。一方面,采用C語(yǔ)言設(shè)計(jì)效率較高,利于實(shí)現(xiàn)模塊化、組態(tài)化的設(shè)計(jì)目標(biāo)。另一方面,信號(hào)采集處理頻率較高,如400Hz交流信號(hào)、頻率信號(hào)和分辨率較高的開關(guān)量信號(hào);同時(shí),程序運(yùn)行既要符合mC/OS-II時(shí)鐘節(jié)拍,也要滿足數(shù)據(jù)總線上大小周期的定義。這導(dǎo)致對(duì)定時(shí)的要求較高,對(duì)中斷程序設(shè)計(jì)要求嚴(yán)格。因此混合編程是合理的編程方式。
一般混合編程方法
混合編程的一般方法有三種:一是對(duì)C程序編譯后形成的匯編程序進(jìn)行手工的修改與優(yōu)化。二是直接在C語(yǔ)言程序中嵌入?yún)R編語(yǔ)句。三是分別編寫C程序和匯編程序,再獨(dú)立編譯成目標(biāo)代碼模塊,再進(jìn)行鏈接。
第一種編程方式要求對(duì)匯編與C語(yǔ)言都極其熟悉,并且這樣的編程方式對(duì)程序的可讀性和擴(kuò)展性的負(fù)面影響比較大。第二種方法適用于語(yǔ)句執(zhí)行頻率非常高,并且C編程與匯編編程效率差異較大的情況,例如進(jìn)入中斷的通用中斷子程序等。第三種方式是混合編程最常用的方式之一。在這種方式下,C程序與匯編程序均可使用另一方定義的函數(shù)與變量。
變量定義的規(guī)則與數(shù)組、指針的使用
變量定義是混合編程的基本問(wèn)題。C程序與匯編程序定義的變量相互之間可以進(jìn)行訪問(wèn)。在匯編程序中定義時(shí),需要在變量前加下劃線“_”,然后再用.global定義為全局變量。在C程序中則需要說(shuō)明為extern變量。
C語(yǔ)言中常用的數(shù)組與指針也可以很方便地在匯編程序中定義并互相訪問(wèn)。如例,在匯編語(yǔ)言中用.usect定義占用6*32個(gè)字的全局變量_AC_RSLT,在C程序中被說(shuō)明成一個(gè)6*32的16位無(wú)符號(hào)數(shù)的二位數(shù)組。當(dāng)然,在匯編程序中,數(shù)據(jù)的存放格式需要滿足C對(duì)二維數(shù)組數(shù)據(jù)存放格式的要求。即在存儲(chǔ)器中,從低地址到高地址,二維數(shù)組的內(nèi)容從第一行起各行依次放入存儲(chǔ)器中。實(shí)際上,這個(gè)數(shù)組定義也可以看作是指針定義。
匯編程序:
_AC_RSLT .usect “ADDATA”, (6*32)
.global _AC_RSLT
C程序:
extern INT16U AC_RSLT[6][32];
( extern INT16U *AC_RSLT; )
依此類推,只要具有明確的數(shù)據(jù)存放格式,C語(yǔ)言中各種類型的變量在匯編語(yǔ)言中都可以方便地定義和使用。
函數(shù)調(diào)用的一般規(guī)則
C程序中調(diào)用匯編函數(shù)
C程序中調(diào)用的匯編函數(shù),在匯編中其名稱以程序標(biāo)號(hào)的形式出現(xiàn)。程序標(biāo)號(hào)作為操作數(shù)用.global進(jìn)行定義。并且同變量一樣,在前面加下劃線“_”。匯編函數(shù)也可以給調(diào)用者傳遞返回值,它實(shí)際上是通過(guò)被寫入累加器返回的。匯編函數(shù)一般具有如下例的形式:
_calcu:
POPD *+ 將返回地址壓入任務(wù)棧
SAR AR0, *+ 存儲(chǔ)調(diào)用者的幀指針
SAR AR1, *
LAR AR0, #01h
LAR AR0, *0+,AR2 堆棧指針復(fù)制到AR0并創(chuàng)建局部幀
SETC SXM 注意: 改變了狀態(tài)寄存器
MAR *, AR2
LAR AR2, #0FFFDh AR2=-3
MAR *0+
LACC * 訪問(wèn)調(diào)用者傳遞的參數(shù)
...
MAR *, AR3
LACL * 傳遞返回值
MAR *, AR1
SBRK #02h
LAR AR0, *-
PSHD *
RET
匯編程序中調(diào)用C函數(shù)
匯編程序中調(diào)用C函數(shù)相對(duì)比較簡(jiǎn)單,編譯器已經(jīng)提供了相當(dāng)完善的支持。函數(shù)在C中需要用extern進(jìn)行定義,函數(shù)名加“_”后在匯編程序中用.ref說(shuō)明為外部標(biāo)號(hào)。在調(diào)用函數(shù)之前應(yīng)手工編程將參數(shù)以逆序?qū)懭氲疆?dāng)前運(yùn)行任務(wù)所使用的任務(wù)堆棧中,壓棧之前堆棧指針可不作調(diào)整。被調(diào)用的C函數(shù)即可正常訪問(wèn)調(diào)用者傳遞的參數(shù),函數(shù)調(diào)用完畢后需要調(diào)整堆棧指針,清除函數(shù)調(diào)用中參數(shù)所占用的堆棧空間。C函數(shù)的返回值可以通過(guò)訪問(wèn)累加器獲得。





