常⽤ARM指令
常⽤ARM指令1:数据处理指令
  mov mvn
  MOV(MOVE)指令可完成从另⼀个寄存器、被移位的寄存器或将⼀个⽴即数加载到⽬的寄存器
MOV R0,R1;R1的值传到R0
MOV R3,#3 ;把常数3传给R3
MVN( MOVE Negative)取反后再传值,⽐MOV多了⼀步取反
MVN R0, #0 ;把0取反(即-1)传给R0
MVN R1,R2  ;把R2的值取反传给R1
  算术指令
  add sub rsb adc sbc rsc
  ADD加法指令
  ADD R0,R1,R2; R0=R1+R2
  ADD R0,R1,#3 ;R0=R1+3
  ADC带进位加法指令,即除了加两个数以外,还要把CPSR的C值也要带进来
  通常⽤于⼤数(超过32Bit整数)相加,这时单⽤ADD不能处理,必须折成两步,其中⼀步⽤ADC.
  以下是做64Bit的加法
  ADDS R0,R1,R2; R0=R1+R2,ADDS中S表⽰把进位结果写⼊CPSR
  ADC R5,R3,R4 ;R5=R3+R4+C
  逻辑指令
  and orr eor bic
  AND位与指令
  AND R0,R1,R2; R0=R1 & R2
  AND R0,R1,#0xFF ;R0=R1 & 0xFF
  ORR位或指令
  ORR R0,R1,R2; R0=R1 | R2
  ORR R0,R1,#0xFF ;R0=R1 | 0xFF
  TST测试某⼀位是否为1,并把结果写⼊CPSR,供下⼀句使⽤
  TST R1,#0xffe;  等同于if(R1 & 0xffe)
  TST R1,#%1;测试最低位是否为1,%表⽰⼆进制
  BIC清位操作
  BIC  R0,R0,#0xF;等同于 R0 &=~(0xF)
  BIC  R0,R0,#%1011;该指令清除 R0 中的位 0 1  3,其余的位保持;  %表⽰是⼆进制,0x表⽰⼗六进制  ⽐较指令
  cmp cmn tst teq
  CMP⽐较两个操作数,并把结果存⼊CPSR供下⼀句语句使⽤
  CMP R0,R1; ⽐较R0,R1
  乘法指令
  mvl mla umull umlal smull small
  MUL R0,R1,R2 ;R0 = R1 × R2
MULS R0,R1,R2 ;R0 = R1 × R2,同时设置CPSR中的相关条件标志位
  MLA R0,R1,R2,R3            ;R0 = R1 × R2 + R3
MLAS  R0× R2 + R3,同时设置CPSR中的相关条件标志位
  SMULL  R0,R1,R2,R3 ;R0 = (R2 × R3)的低32位
  ;R1 = (R2 × R3)的⾼32位
  加载/存储指令 LDR,STR 
  LDR R0,[R1]; R1的值当成地址,再从这个地址装⼊数据到R0 (R0=*R1)
  LDR R1,=0x30008000 ; 把地址0x30008000的值装⼊到R1中
  STR R0,[R1] ; 把R0的值,存⼊到R1对应地址空间上(*R1 = R0)。
  STR R0,=0x30008000 ;把R0中值存⼊到地址0x30008000
常⽤ARM指令2:cpsr访问指令
  mrs & msr
  mrs⽤来读psr,msr⽤来写psr
  CPSR寄存器⽐较特殊,需要专门的指令访问,这就是mrs和msr。
常⽤ARM指令3:跳转(分⽀)指令
  b & bl & bx
  b 直接跳转(就没打开算返回)
  B main ;跳转到标号为main地代码处
    bl branch and link,跳转前把返回地址放⼊lr中,以便返回,以便⽤于函数调⽤  bx跳转同时切换到ARM模式,⼀般⽤于异常处理的跳转
常⽤ARM指令4:访存指令
  ldr/str & ldm/stm & swp
  单个字/半字/字节访问 ldr/str
  多字批量访问  ldm/stm
  swp r1, r2, [r0]
  swp r1, r1, [r0]
常⽤ARM指令5:软中断指令
  swi(software interrupt)
  软中断指令⽤来实现操作系统中系统调⽤
协处理器cp15操作指令
  mcr & mrc
  mrc⽤于读取CP15中的寄存器
  mcr⽤于写⼊CP15中的寄存器
  MRC & MCR的使⽤⽅法
  mcr{<cond>}  p15, <opcode_1>, <Rd>, <Crn>, <Crm>, {<opcode_2>}
  opcode_1:对于cp15永远为0
  Rd:ARM的普通寄存器
  Crn:cp15的寄存器,合法值是c0~c15
  Crm:cp15的寄存器,⼀般均设为c0
  opcode_2:⼀般省略或为0
  mrc p15, 0, r0, c1, c0, 0
  orr  r0, r0, #1
  mcr p15, 0, r0, c1, c0, 0
8种后缀
  ia(increase after)先传输,再地址+4
  ib(increase before)先地址+4,再传输
  da(decrease after)先传输,再地址-4
  db(decrease before)先地址-4,再传输
  fd(full decrease)满递减堆栈
  ed(empty decrease)空递减堆栈
  fa(·······)满递增堆栈
  ea(·······)空递增堆栈
四种栈
  空栈:栈指针指向空位,每次存⼊时可以直接存⼊然后栈指针移动⼀格;⽽取出时需要先移动⼀格才能取出
  满栈:栈指针指向栈中最后⼀格数据,每次存⼊时需要先移动栈指针⼀格再存⼊;取出时可以直接取出,然后再移动栈指针  增栈:栈指针移动时向地址增加的⽅向移动的栈
  减栈:栈指针移动时向地址减⼩的⽅向移动的栈
!的作⽤
  ldmia    r0, {r2 - r3}
  ldmia    r0!, {r2 - r3}
  感叹号的作⽤就是r0的值在ldm过程中发⽣的增加或者减少最后写回到r0去,也就是说ldm时会改变r0
的值。
^的作⽤
  ldmfd    sp!, {r0 - r6, pc}
  ldmfd    sp!, {r0 - r6, pc}^
  ^的作⽤:在⽬标寄存器中有pc时,会同时将spsr写⼊到cpsr,⼀般⽤于从异常模式返回。
伪指令的意义
  伪指令不是指令,伪指令和指令的根本区别是经过编译后会不会⽣成机器码。
  伪指令的意义在于指导编译过程。
  伪指令是和具体的编译器相关的,我们使⽤gnu⼯具链,因此学习gnu环境下的汇编伪指令。
gnu汇编中的⼀些符号
  @ ⽤来做注释。可以在⾏⾸也可以在代码后⾯同⼀⾏直接跟,和C语⾔中//类似
  # 做注释,⼀般放在⾏⾸,表⽰这⼀⾏都是注释⽽不是代码。
  :以冒号结尾的是标号
  .  点号在gnu汇编中表⽰当前指令的地址
  # ⽴即数前⾯要加#或$,表⽰这是个⽴即数
常⽤gnu伪指令
  .global _start              @ 给_start外部链接属性  .section .text        @ 指定当前段为代码段
  .ascii .byte .short .long .word
  .quad .float .string @ 定义数据
  .align 4                @ 以16字节对齐
  .balignl 16 0xabcdefgh    @ 16字节对齐填充偶尔会⽤到的gnu伪指令
  .end                    @标识⽂件结束
  .include              @ 头⽂件包含
  .arm / .code32    @声明以下为arm指令
  .thumb / .code16 @声明以下为thubm指令
最重要的⼏个伪指令
  ldr          ⼤范围的地址加载指令
  adr  ⼩范围的地址加载指令
  adrl 中等范围的地址加载指令
  nop 空操作
比较指令cmp怎么用

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。