ARM常见汇编指令总结

文章目录

  • 前言
  • 一、跳转指令
  • 二、比较指令
  • 三、位移指令
  • 四、位运算
  • 五、待更新
  • 总结


前言

在平常调试芯片代码或者看数字仿真波形的过程中,常常会需要对软件代码的反汇编文件进行查看,因此有必要掌握arm常见的一些汇编指令,下面是以armv8-m手册中的指令作为参考并加上一些自己的总结。


一、跳转指令

  • B (Branch)
    常见用法:B{}  
imm32 =  SignExtend(imm8:'0', 32)
BranchTo(PC + imm32); 

  其中PC+imm32就是label的位置。注意imm32是由imm8通过符号扩展的方式生成的,也就是imm8的符号位也对应着imm32的符号位,可正可负,即可以往当前PC的前或者后进行相对跳转。B指令总共存在四种变体,主要是指令长度不同(2字节或4字节),由此对应出跳转的偏移量不同,四种变体对应的跳转偏移量:-256~254, -2048~2046, -1048576~1048574, -16777216~16777214。

  • BL (Branch with Link)
    常见用法:BL{}{}  

  • BX (Branch and eXchange)
    常见用法:BX{}{}  
    address = R[m],PC = address
    与前面的B指令不同,BX指令不再是跳转至PC的相对地址,而是以寄存器Rm中存的值作为绝对地址进行跳转,另外BX的exchange指的是:根据address[0]判断cpu的切换状态,1代表thumb state、0代表arm state。由于armv8-m仅支持thumb指令,因此Rm寄存器中值的最低位必须为1,否则将会产生不可预测的错误。

  • BLX (Branch with Link and eXchange)
    常见用法:BLX{}{}  
    这条指令是BL和BX指令的结合体,当然功能也是二者的一个结合:跳转至Rm寄存器中保存的绝对地址,并且在跳转之前会保存返回地址到LR寄存器中(这里不讨论中断情况)

简单总结下:跳转指令中,带有字母L说明需要保存返回值到LR寄存器中,否则不需要保存;带有字母X说明以寄存器中的值作为绝对地址进行跳转,否则,汇编器会计算出label与PC的偏移量然后进行相对跳转(具有跳转范围限制)。


二、比较指令

  • CBNZ, CBZ
    ​ 例: CBZ{} , 

​   将寄存器Rn中的值与0比较,满足条件便跳转至label:BranchWritePC(PC + imm32)

​   其中imm32 = ZeroExtend(i:imm5:‘0’, 32),由此可知,label只能在当前PC的前方位置,且距离不能超 过 2^7= 128bytes

  • CMP (immediate or register)

    • T1: CMP{}{} , #
    • T2: CMP{}{} , #
    • CMP{}{} ,
    • CMP{}{} , , #

    将立即数或者Rm或者经过移位后的Rm中的值的补码与Rn相加(相当于做减法),并根据结果更新CPSR寄存器里的N,Z,C,V,由此可知两个比较数的大小关系

  • APSR中N,Z,C,V的含义
    ARM常见汇编指令总结_第1张图片


三、位移指令

常见的移位指令有以下几种,LSL(逻辑左移),LSR(逻辑右移),ASR(算数右移),ROR(循环右移),ROR(循环右移),RRX。

  • LSL
    ARM常见汇编指令总结_第2张图片
    由伪代码可知,逻辑左移shift位之后,会在右边补shift位的0,并且会把最后左移出的位作为进位值

  • LSR
    ARM常见汇编指令总结_第3张图片
    由伪代码可知,逻辑右移shift位之后,会在左边补shift位0,并将最后右移出的位作为进位值

  • ASR
    ARM常见汇编指令总结_第4张图片
    由伪代码可知,算数右移shift位之后,会根据原本的符号位在左边补上shift个符号位,并将最后右移出的位作为进位值

  • ROR
    ARM常见汇编指令总结_第5张图片
    由伪代码可知,循环右移shift位后,会将移除的数据放进左边,如果循环移位32次,那么这个数不会改变

  • RRX

ARM常见汇编指令总结_第6张图片

四、位运算

  • 按位与
    AND (immediate) or (register)
    常见用法如下:
    T1 : AND{}{} {, } , #
    T2 : AND{}{} {, } , 
    T3 : AND{}{} {, } ,  {,  #}
    将立即数或者(移位后)的寄存器(Rm)的值与寄存器Rn中的值按位相与的结果写入Rd中。并可以选择是否更新APSR中的位

  • 按位或
    ORR (immediate) or (register)
    常见用法如下
    T1 : ORR{}{} {,} , #
    T2 : ORR{}{} {,} , 
    T3 : ORR{}{} {,} ,  {, #}
    将立即数或者(移位后)的寄存器(Rm)的值与寄存器Rn中的值按位相或的结果写入Rd中。并可以选择是否更新APSR中的位

  • 按位取反
    MVN (immediate) or (register)
    常见用法如下
    T1 : MVN{}{} , #
    T2 : MVN{}{} , 
    T3 : MVN{}{} ,  {, #}
    将立即数或者(移位后)的寄存器(Rm)的值按位取反的结果写入Rd中。并可以选择是否更新APSR中的位

  • 异或
    EOR (immediate) or (register)
    常见用法如下:
    T1 : EOR{}{} {,} , #
    T2 : EOR{}{} {,} , 
    T3 : EOR{}{} {,} ,  {, #}
    将立即数或者(移位后)的寄存器(Rm)的值与寄存器Rn中的值按位异或的结果写入Rd中。并可以选择是否更新APSR中的位

五、待更新

总结

以上总结了一部分arm汇编中常出现的一些指令,以后有时间会接着补充。
熟悉汇编指令后除了能方便平常调试以外,更有意思的是将汇编代码直接嵌入在自己的程序当中,C内嵌汇编能让开发者在C的基础上更加接近底层,并能最大限度的优化程序运行效率,后续将会介绍C语言中如何内嵌汇编。

你可能感兴趣的:(技术分享,arm)