1、為什么要混合編程?
匯編語言:執行效率高,編寫繁瑣 C語言:可讀性強,移植性好,調試方便 應用在對執行效率有要求的場合、能夠更直接地控制處理器
(1)匯編調用c函數 很簡單,在匯編程序中直接ldr: 例如:ldr pc,=gboot_main (備注:gboot_main是main.c中的一個子函數,需要修改makefile,見上一篇博客)
(2)c調用匯編 在匯編中用標號注明,并設置為全局,然后再c語言中直接引用函數(標號(),例如 light_led( );)。
.global light_ledlight_led: ldr r0, =GPBCON mov r1, #0x400 str r1, [r0] ldr r0, =GPBDAT mov r1, #0x0 str r1, [r0] mov pc, lr(3)c內嵌匯編
_arm__( 匯編語句部分 :輸出部分 (凡是要寫進去的參數都寫到輸出部分) :輸入部分 (凡是要讀的參數都寫到輸入部分) :破壞描述部分 ); 后面三個部分可以省略,也可以arm開頭。
例1:(輸出:在匯編中被修改的C變量列表)
void long read_p15_c1(void){ unsigned long value; _arm_( "mrc p15,0,%0,c1,c0,0/n" :"r"(value) @'='表示只寫操作數,用于輸出部 : :“memory” ); return value;}讀取數據 到r*寄存器,并復制到變量value中去,因為value是存在于棧區(即內存中),所以破壞區要加上“memory”
例2:(輸入:作為參數輸入到匯編中的變量列表)
void write_p15_c1(unsigned long value){ _arm_( "mcr p15,0,%0,c1,c0,0/n" : :"r"(value) @編譯器選擇一個R*寄存器 );}上面的%0表示 0 號參數(通用寄存器,系統自動分配一個寄存器),從這個參數中讀取數據(值從value中獲取)寫到c1寄存器中。
例3:(volatile)
例4:(使用內嵌匯編點亮LED)
#dedine GPKCON 0X7f008800#define GPKDAT 0x7f008808int gboot_main(){ _arm_( "ldr r1,=0x11110000/n" "str r1,[%0]/n" "ldr r1,=0xa0/n" "str r1,[%1]/n" : :"r"(GPKCON),"r"(GPKDAT) @輸入 :"r1" @因為上面修改了r1寄存器,所以放在破壞區 ); return 0;}新聞熱點
疑難解答
圖片精選