c與彙編混合程式設計
阿新 • • 發佈:2019-01-10
1、為什麼要混合程式設計?
組合語言:執行效率高,編寫繁瑣
C語言:可讀性強,移植性好,除錯方便
應用在對執行效率有要求的場合、能夠更直接地控制處理器
(1)彙編呼叫c函式
很簡單,在彙編程式中直接ldr:
例如:ldr pc,=gboot_main
(備註:gboot_main是main.c中的一個子函式,需要修改makefile,見上一篇部落格)
(2)c調用匯編
在彙編中用標號註明,並設定為全域性,然後再c語言中直接引用函式(標號(),例如 light_led( );)。
.global light_led
light_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 0x7f008808
int 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;
}