內(nèi)聯(lián)匯編即在C中直接使用匯編語(yǔ)句進(jìn)行編程,使程序可以在C程序中實(shí)現(xiàn)C語(yǔ)言不能完成的一些工作,例如,在下面幾種情況中必須使用內(nèi)聯(lián)匯編或嵌入型匯編
程序中使用飽和算術(shù)運(yùn)算(Saturating Arithmetic)
程序需要對(duì)協(xié)處理器進(jìn)行操作
在C程序中完成對(duì)程序狀態(tài)寄存器的操作
__asm__ __volatile__("asm code":output:input:changed registers);
Note:
使用__asm__和__volatile__表示編譯器將不檢查后面的內(nèi)容,而是直接交給匯編器。
如果希望變壓器你優(yōu)化,__volatile__可以不加
沒(méi)有asm code也不能省略""
沒(méi)有前面的和中間的部分,不可以相應(yīng)的省略:
沒(méi)有changed 部分,必須相應(yīng)的省略:
最后的;不能省略,對(duì)于C語(yǔ)言來(lái)說(shuō)這是一條語(yǔ)句
匯編代碼必須放在一個(gè)字符串內(nèi),且字符串中間不能直接按回車換行,可以寫(xiě)成多個(gè)字符串,注意中間不能有任何符號(hào),這樣就會(huì)將兩個(gè)字符串合并為一個(gè)指令之間必須要換行,還可以使用\t使指令在匯編中保持整齊
asm code
"mov r0, r0\n\t""mov r1,r1\n\t""mov r2,r2"
output(asm->C)
:"constraint" (variable)
"constraint"用于定義variable的存放位置:
r表示使用任何可用的寄存器
m表示使用變量的內(nèi)存地址
+可讀可寫(xiě)
=只寫(xiě)
&表示該輸出操作數(shù)不能使用輸入部分使用過(guò)的寄存器,只能用"+&"或"=&"的方式使用
input(C->asm)
:"constraint" (variable/immediate)
"constraint"用于定義variable的存放位置:
r表示使用任何可用的寄存器(立即數(shù)和變量都可以)
m表示使用變量的內(nèi)存地址
i表示使用立即數(shù)
例子
int a=100,b=200;int result;__asm__ __volatile__( "mov %0,%3\n\t" //%0是一個(gè)占位符,表示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));
ATPCS
子程序間通過(guò)寄存器R0~R3來(lái)傳遞參數(shù),如果參數(shù)多于四個(gè),則多出的部分用堆棧傳遞,被調(diào)用的子程序在返回前無(wú)須恢復(fù)寄存器R0~R3的內(nèi)容
在子程序中,使用寄存器R4~R11來(lái)保存局部變量,如果在子程序中使用到了R4~R11中的某些寄存器,子程序進(jìn)入時(shí)必須保存這些寄存器的值,在返回前必須恢復(fù)這些寄存器的值;對(duì)于子程序中沒(méi)有用到的寄存器則不必進(jìn)行這些操作,在Thumb程序中,通常只能使用寄存器R4~R7來(lái)保存局部變量
R12用作子程序間scrtach寄存器(用于保存SP,在函數(shù)返回時(shí)使用該寄存器出棧),記作ip
R13用作數(shù)據(jù)棧指針,記作sp
R14用作連接寄存器,記作lr
R15記作程序寄存器,記作pc
相互調(diào)用
C和匯編相互調(diào)用要特別注意遵守相應(yīng)的ATPCS規(guī)則
C調(diào)用匯編
//.c#include extern void strcopy(char* des, const char* src);int main(){ const char* srcstr = "src string"; char desstr[]="des string"; strcopy(desstr, srcstr); return 0;}
;.asm.global strcopystrcopy: ;R0指向目的字符串 ;R1指向源字符串 LDRB R2, [R1], #1 ;加載字節(jié)并更新源字符串指針地址 STRB R2, [R0], #1 ;存儲(chǔ)季節(jié)并更新目的字符串指針地址 CMP R2, #0 ;判斷是否為字符串結(jié)尾 BNE strcopy ;如果不是,程序跳轉(zhuǎn)到strcopy繼續(xù)循環(huán) MOV pc, ir ;程序返回
匯編調(diào)用C
//.cint fcn(int a, int b , int c, int d, int e){ return a+b+c+d+e;}
;.asm;假設(shè)程序進(jìn)入f時(shí),R0中的值為i;int f(int i){return fcn(i, 2*i, 3*i, 4*i, 5*i);}.text.global _start_start: STR lr, [sp, #-4]! ;保存返回地址lr ADD R1, R0, R0 ;計(jì)算2*i(第2個(gè)參數(shù)) ADD R2, R1, R0 ;計(jì)算3*i(第3個(gè)參數(shù)) ADD R3, R1, R2 ;計(jì)算5*i STR R3, [SP, #-4]! ;第5個(gè)參數(shù)通過(guò)堆棧傳遞 ADD R3, R1, R1 ;計(jì)算4*i(第4個(gè)參數(shù)) BL fcn ;調(diào)用C程序 ADD sp, sp, #4 ;從堆棧中刪除第五個(gè)參數(shù) .end
?
評(píng)論