1. 程式人生 > >c與彙編混合程式設計

c與彙編混合程式設計

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;
}