arm 复杂指令集,arm支持哪几种指令集
1.跳转指令:b,BL(带回车),BLX,BX(带状态)
2.数据传输:MOV(通用寄存器区)、MVN(逐位反转)、CMP(比较结果中存在CPSR)、TST(逐位)、ADD、SUB、AND、ORR、BIC、MUL、
3.访问状态寄存器:MSR夫人
二。汇编指令集
1、LDR、STR(B)
2、STR、
3.LDM和STM(批处理)
4、swp
5、LSL、罗
6、SWI、BKPT
三。伪指令
1、GBLA、GBLL、GBLS、LCLA、LCLL、LCLS、塞塔、SETL、塞特、
2、RLIST
3.分配存储单元
4、空间
5、地图
6、如果、否则、结束
WHILE,WEND,
8、地区、代码、仅、出口、进口
四。C与汇编的混合编程
在嵌入式系统的开发中,目前使用的主要编程语言是C和汇编。c有相应的编译器,但是现在用的还是比较少。在一些大型的嵌入式软件中,比如OS,大部分代码都是用C写的,主要是因为C语言结构好,容易让人理解,有大量的支持库。尽管如此,汇编语言还是在很多地方使用,比如硬件系统启动时的初始化,包括CPU状态的设置,中断的使能,主频的设置,RAM的控制参数和初始化。一些中断处理方面也可能涉及汇编。使用汇编的另一个地方是一些对性能非常敏感的代码块。不是依靠C编译器生成代码,而是需要手动编译汇编来达到优化的目的。而且,汇编语言与CPU的指令集紧密相连。由于嵌入式系统的开发涉及到底层,所以需要熟练使用相应的汇编语言。
纯C或汇编编程,请参考相关书籍或手册。这里主要讨论C和汇编的混合编程,包括两者之间的函数调用。下面讨论四种情况,暂时不涉及C。
1.C语言中的嵌入式程序集
C中嵌入的汇编指令包含了大部分的ARM和Thumb指令,但它们的使用与汇编文件中的有些不同,存在一定的局限性,主要表现在以下几个方面:
A.不能直接给PC寄存器赋值,程序跳转要用b或BL指令。
B.使用物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突。
C.R12和R13可能被编译器用来存储中间编译结果,R0到R3、R12和R14可能被用于计算表达式值时的子例程调用,因此应该避免直接使用这些物理寄存器。
D.一般不需要直接指定物理寄存器,而是让编译器来分配。
内联程序集中使用的标记是__asm或asm关键字,其用法如下:
__asm
{
指令[;说明]
…
[说明]
}
asm("说明[;说明]”);
下面的例子说明了如何在C语言中嵌入汇编语言,
#包含stdio.h
void my_strcpy(const char *src,char *dest)
{
char ch
__asm
{
循环:
ldrb通道,[src],#1
strb ch,[dest],#1
cmp通道,#0
bne回路
}
}
int main()
{
char *a=忘了它,继续前进!;
char b[64];
my_strcpy(a,b);
printf(原件:%s ,a);
printf(已复制:%s ,b);
返回0;
}
在这里,C和程序集之间的值传递是通过C的指针来实现的,因为指针对应的是地址,所以也可以在程序集中访问。
2.在程序集中使用C定义的全局变量
嵌入式汇编不需要单独编辑汇编语言文件,相对简单,但是有很多限制。当有许多代码需要汇编时,它们通常放在一个单独的汇编文件中。这时候就需要在汇编和c之间传递一些数据,最简单的方法就是使用全局变量。
/* cfile.c
*定义全局变量,并充当调用程序。
*/
#包含stdio.h
int gVar _ 1=12
extern ASM double(void);
int main()
{
printf( gVar _ 1的原始值为:%d ,gVar _ 1);
ASM double();
printf( gVar _ 1的修改值为:%d ,gVar _ 1);
返回0;
}
相应的汇编语言文件
;由main(在C中)调用,将一个整数加倍,使用C中定义的全局变量。
区域asmfile,代码,只读
导出为双精度
导入gVar_1
asmDouble
ldr r0,=gVar_1
ldr r1,[r0]
2号mov r2
mul r3,r1,r2
字符串r3,[r0]
mov pc,lr
结束
3.在c中调用汇编函数。
在C中调用汇编文件中的函数主要有两项工作要做,一是在C中声明函数原型,添加extern关键字;二是使用EXPORT导出程序集中的函数名,并将函数名作为汇编代码段的标识符,最后用MOVPC和LR返回。然后,你可以在C中使用这个函数,从C的角度来说,我们不知道函数是用C还是汇编实现的。更深层次的原因是C的函数名起到了指示函数代码起始地址的作用,与汇编标签一致。
/* cfile.c
*在C中,调用asm函数asm_strcpy
* 2004年9月9日
*/
#包含stdio.h
extern void ASM _ strcpy(const char * src,char * dest);
int main()
{
const char *s=阳光下的季节;
char d[32];
asm_strcpy(s,d);
printf(source: %s ,s);
printf(目的地:%s ,d);
返回0;
}
;asm功能实现
区域asmfile,代码,只读
导出asm_strcpy
asm_strcpy
环
ldrb r4,[r0],# 1;读取后地址增量
cmp r4,#0
结束了
strb r4,[r1],#1
b循环
超过
mov pc,lr
结束
这里C和汇编之间的参数传递是通过AT PCS(arm thumb procedure call standard)的规定进行的。简单来说,如果函数的参数不超过四个,那么相应的参数由R0-R3传递。当参数超过四个时,函数的返回值由R0返回。
4.在程序集中调用C的函数
要在程序集中调用C的函数,需要在程序集中导入相应的C函数名,然后将C代码放到独立的C文件中进行编译。剩下的工作由连接器处理。
;参数传递的细节来自ATPCS
;如果有4个以上的参数,将使用堆栈
导出asmfile
区域asmfile,代码,只读
导入cFun
进入
mov r0,#11
mov r1,#22
mov r2,#33
BL cFun
结束
/*C文件,由asmfile调用*/
int cFun(int a,int b,int c)
{
返回一个b c;
}
在汇编中调用C的函数,参数的传递也是通过ATPCS实现的。需要指出的是,当函数的参数个数大于4时,应该使用stack。详情参见ATPCS规范。
动词(verb的缩写)ARM协处理器
1.协处理器芯片,CP15,
CDP、LDC、STC、MCR、MRC
3.MRC p15,0,r1,c0,c0,2将状态C0放入寄存器r1
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。