开发Arm程序的时分,大多数时分运用C/C++言语就能够了,但汇编言语在某些情况下能够完结一些C言语无法完结的功用,这时分就要调用一些汇编言语的程序.咱们需求大约了解一下在C言语中怎么嵌入汇编言语.
1.内嵌汇编言语的语法:
__asm
{
指令[;指令]
……
[指令]
}
2.举例:使能/制止IRQ中止
__inline void enable_IRQ(void)
{
int tmp;
__asm//嵌入汇编代码
{
MRStmp,CPSR//读取CPSR的值
BICtmp,tmp,#0x80//将IRQ中止制止位I清零,即答应IRQ中止
MSRCPSR_c,tmp//设置CPSR的值
}
}
__inline void disable_IRQ(void)
{
int tmp;
__asm
{
MRStmp,CPSR
ORRtmp,tmp,#Ox80
MSRCPSR_c,tmp
}
}
3.举例:字符串仿制
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.内嵌汇编的指令用法:
.操作书: 内嵌的汇编指令中作为操作数的寄存器和常量可所以C表达式.这些表达式可所以char,short或int等类型,并且这些表达式都是作为无符号数进行操作的.若要有符号数,用户需求自己处理与符号有关的操作.编译器将会核算这些表达式的值,并为其分配寄存器.
.物理寄存器:内嵌汇编中运用物理寄存器是有约束的:
_ 不能直接向PC(程序计数器)寄存器中赋值,程序跳转只能经过B或BL指令来完结.
_ 运用物理寄存器的指令中,不要运用过于杂乱的C表达式
_ 尽可能少的运用物理寄存器
.常量: 在内嵌汇编指令中,常量前面的”#”能够省掉
.标号: C程序中的标号能够被内嵌的汇编指令运用.可是只要指令B能够运用C程序中的标号,而指令BL则不能运用.
.内存单元的分配:一切内存分配均由C编译器完结,分配的内存单元经过变量供内嵌汇编器运用.内嵌汇编器不支持内嵌汇编程序中用于内存分配的伪指令.
5.内嵌汇编注意事项:
.有必要当心运用物理寄存器,如R0~R3,IP,LR,CPSR中的标志位,防止发生冲突.
例如:
__asm
{
MOVR0,x
ADDy,R0,x/y
}
改成下面代码会比较稳当:
__asm
{
MOV var,x
ADD y,var,x/y
}
.不要运用寄存器替代变量.
.运用内嵌汇编无需保存和康复寄存器.事实上,除了CPSR,SPSR寄存器,对物理寄存器先读后写都会引起汇编报错.
.汇编言语中”,”号作为操作数分隔符.如果有C表达式作为操作数,若表达式中包括有”,”,则有必要运用()将其规约为一个汇编操作数,例如:
__asm
{
ADD x,y,(f(),z)//”f(),z”为带有”,”的C表达式.
}
6.不同数据类型对应的汇编指令:
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
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/274925.html