內聯彙編即在c中直接使用彙編語句進行程式設計,使程式可以在c程式中實現c語言不能完成的一些工作,例如,在下面幾種情況中必須使用內聯彙編或嵌入型彙編
程式中使用飽和算術運算(saturating arithmetic)
程式需要對協處理器進行操作
在c程式中完成對程式狀態暫存器的操作
__asm__ __volatile__("asm code":output:input:changed registers);
note:
使用__asm__
和__volatile__
表示編譯器將不檢查後面的內容,而是直接交給彙編器。
如果希望變壓器你優化,__volatile__
可以不加
沒有asm code也不能省略""
沒有前面的和中間的部分,不可以相應的省略:
沒有changed 部分,必須相應的省略:
最後的;
不能省略,對於c語言來說這是一條語句
彙編**必須放在乙個字串內,且字串中間不能直接按回車換行,可以寫成多個字串,注意中間不能有任何符號,這樣就會將兩個字串合併為乙個
指令之間必須要換行,還可以使用\t
使指令在彙編中保持整齊
"mov r0, r0\n\t"
"mov r1,r1\n\t"
"mov r2,r2"
:"constraint" (variable)
"constraint"
用於定義variable的存放位置:
r
表示使用任何可用的暫存器
m
表示使用變數的記憶體位址
+
可讀可寫
=
只寫
&
表示該輸出運算元不能使用輸入部分使用過的暫存器,只能用"+&"
或"=&"
的方式使用
:"constraint" (variable/immediate)
"constraint"
用於定義variable的存放位置:
r
表示使用任何可用的暫存器(立即數和變數都可以)
m
表示使用變數的記憶體位址
i
表示使用立即數
int a=100,b=200;
int result;
__asm__ __volatile__(
"mov %0,%3\n\t" //%0是乙個佔位符,表示result,之後的類推
"ldr r0,%1\n\t"
"ldr r1,%2\n\t"
"str r0,%2\n\t"
"str %1,%1\n\t"
:"=r"(result),"+m"(a),"+m"(b)
:"i"(123)
);
子程式間通過暫存器r0~r3來傳遞引數,如果引數多於四個,則多出的部分用堆疊傳遞,被呼叫的子程式在返回前無須恢復暫存器r0~r3的內容
在子程式中,使用暫存器r4~r11來儲存區域性變數,如果在子程式中使用到了r4~r11中的某些暫存器,子程式進入時必須儲存這些暫存器的值,在返回前必須恢復這些暫存器的值;對於子程式中沒有用到的暫存器則不必進行這些操作,在thumb程式中,通常只能使用暫存器r4~r7來儲存區域性變數
r12用作子程式間scrtach暫存器(用於儲存sp,在函式返回時使用該暫存器出棧),記作ip
r13用作資料棧指標,記作sp
r14用作連線暫存器,記作lr
r15記作程式暫存器,記作pc
c和彙編相互呼叫要特別注意遵守相應的atpcs規則
//.c
#include extern void strcopy(char* des, const char* src);
int main()
;.asm
.global strcopy
strcopy: ;r0指向目的字串
;r1指向源字串
ldrb r2, [r1], #1 ;載入位元組並更新源字串指標位址
strb r2, [r0], #1 ;儲存季節並更新目的字串指標位址
cmp r2, #0 ;判斷是否為字串結尾
bne strcopy ;如果不是,程式跳轉到strcopy繼續迴圈
mov pc, ir ;程式返回
//.c
int fcn(int a, int b , int c, int d, int e)
;.asm
;假設程式進入f時,r0中的值為i
;int f(int i)
.text
.global _start
_start:
str lr, [sp, #-4]! ;儲存返回位址lr
add r1, r0, r0 ;計算2*i(第2個引數)
add r2, r1, r0 ;計算3*i(第3個引數)
add r3, r1, r2 ;計算5*i
str r3, [sp, #-4]! ;第5個引數通過堆疊傳遞
add r3, r1, r1 ;計算4*i(第4個引數)
bl fcn ;呼叫c程式
add sp, sp, #4 ;從堆疊中刪除第五個引數
.end
ARM彙編 C語言 混合程式設計
主函式main 第一次實驗 12月4 這是我見過最坑爹的問題 main這個字段不能使用。在release模式下怎麼編譯都過不去,報錯如下 原因 不能使用main這個識別符號。用main main main1 mai都行,就是main不行。原來在debugrel模式下,使用main僅僅是乙個警告,沒想...
ARM彙編和C混合程式設計 筆記
arm復位啟動先執行彙編指令,完成硬體的初始化 為什麼不用c語言?因為c語言無法訪問arm內部的暫存器,例如棧,所以需要彙編來進行初始化 c語言能不能跟彙編相互並且反覆呼叫?不能,因為這樣容易導致區域性變數的混用。彙編呼叫c程式 global start start 將gpj2 3 output l...
C語言與彙編混合程式設計
c語言是乙個系統級的語言,是乙個可以直接深入到硬體最底層操作的語言。在前邊的部分部落格中,我們提到過,對硬體的操作實際上是對硬體控制器中的暫存器或儲存單元進行操作,而在arm架構中,這些暫存器或儲存單元一般是以記憶體對映的方式進行訪問的。在c語言中,指標剛好提供了訪問任意的記憶體位址的方式,因此從語...