arm 复杂指令集,arm支持哪几种指令集

  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

arm 复杂指令集,arm支持哪几种指令集