開發(fā)Arm程序的時候,大多數(shù)時候使用C/C++語言就可以了,但匯編語言在某些情況下能夠?qū)崿F(xiàn)一些C語言無法實現(xiàn)的功能,這時候就要調(diào)用一些匯編語言的程序.我們需要大概了解一下在C語言中如何嵌入?yún)R編語言.1.內(nèi)嵌匯編語言的語法:
本文引用地址:http://m.butianyuan.cn/article/201611/316885.htm__asm
{
指令[;指令]
......
[指令]
}
2.舉例:使能/禁止IRQ中斷
__inline void enable_IRQ(void)
{
int tmp;
__asm//嵌入?yún)R編代碼
{
MRStmp,CPSR//讀取CPSR的值
BICtmp,tmp,#0x80//將IRQ中斷禁止位I清零,即允許IRQ中斷
MSRCPSR_c,tmp//設(shè)置CPSR的值
}
}
__inline void disable_IRQ(void)
{
int tmp;
__asm
{
MRStmp,CPSR
ORRtmp,tmp,#Ox80
MSRCPSR_c,tmp
}
}
3.舉例:字符串復(fù)制
void my-strcpy(const char *src,char *dst)
{
int ch;
__asm
{
loop:
#ifndef __thumb
LDRB ch,[src],#1
STRB ch,[dst],#1
#else
LDRB ch,[src]
ADDsrc,#1
STRB ch,[dst]
ADDdst,#1
#endif
CMP ch,#0
BNE loop
}
}
int main(void)
{
const char *a="Hello world!";
char b[20];
__asm
{
MOVR0,a
MOVR1,b
BL my_strcpy,{R0,R1}
}
return(0);
}
4.內(nèi)嵌匯編的指令用法:
.操作書: 內(nèi)嵌的匯編指令中作為操作數(shù)的寄存器和常量可以是C表達(dá)式.這些表達(dá)式可以是char,short或int等類型,而且這些表達(dá)式都是作為無符號數(shù)進(jìn)行操作的.若要有符號數(shù),用戶需要自己處理與符號有關(guān)的操作.編譯器將會計算這些表達(dá)式的值,并為其分配寄存器.
.物理寄存器:內(nèi)嵌匯編中使用物理寄存器是有限制的:
_ 不能直接向PC(程序計數(shù)器)寄存器中賦值,程序跳轉(zhuǎn)只能通過B或BL指令來實現(xiàn).
_ 使用物理寄存器的指令中,不要使用過于復(fù)雜的C表達(dá)式
_ 盡可能少的使用物理寄存器
.常量: 在內(nèi)嵌匯編指令中,常量前面的"#"可以省略
.標(biāo)號: C程序中的標(biāo)號可以被內(nèi)嵌的匯編指令使用.但是只有指令B可以使用C程序中的標(biāo)號,而指令BL則不能使用.
.內(nèi)存單元的分配:所有內(nèi)存分配均由C編譯器完成,分配的內(nèi)存單元通過變量供內(nèi)嵌匯編器使用.內(nèi)嵌匯編器不支持內(nèi)嵌匯編程序中用于內(nèi)存分配的偽指令.
5.內(nèi)嵌匯編注意事項:
.必須小心使用物理寄存器,如R0~R3,IP,LR,CPSR中的標(biāo)志位,避免發(fā)生沖突.
例如:
__asm
{
MOVR0,x
ADDy,R0,x/y
}
改成下面代碼會比較妥當(dāng):
__asm
{
MOV var,x
ADD y,var,x/y
}
.不要使用寄存器代替變量.
.使用內(nèi)嵌匯編無需保存和恢復(fù)寄存器.事實上,除了CPSR,SPSR寄存器,對物理寄存器先讀后寫都會引起匯編報錯.
.匯編語言中","號作為操作數(shù)分隔符.如果有C表達(dá)式作為操作數(shù),若表達(dá)式中包含有",",則必須使用()將其規(guī)約為一個匯編操作數(shù),例如:
__asm
{
ADD x,y,(f(),z)//"f(),z"為帶有","的C表達(dá)式.
}
6.不同數(shù)據(jù)類型對應(yīng)的匯編指令:
unsigned charLDRB/STRB
unsigned shortLDRH/STRH
unsigned int LDR/STR
char LDRSB/STRSB
short LDRSH/STRSH
7.訪問C程序的變量:
AREAglobals,CODE,READONLY
EXPORTasmsubroutine
IMPORTglobalvar;聲明的外部變量
asmsubroutine
LDRR1,=blobalval
LDRR0,[R1]
ADDR0,R0,#1
STRR0,[R1]
MOVPC,LR
END
評論