ARM常见汇编指令总结


前言

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


一、跳转指令

  • B (Branch)
    常见用法:B<c>{<q>}   <label>
    此指令有四种变体,不同的变体可以跳转不同的偏移量,比如
    在这里插入图片描述
    跳转逻辑:
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{<c>}{<q>}   <label>
    在这里插入图片描述与指令B类似,只不过只有一种四字节指令形式,跳转范围是-16777216~16777214,唯有一点不同,就是在跳转到label之前,会将当前指令的下一个地址保存至LR寄存器中,这样可以使得跳出去之后还能跳回来,此命令一般出现在函数跳转的时候。

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

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


二、比较指令

  • CBNZ, CBZ
    ​ 例: CBZ{<q>} <Rn>, <label>
      CBNZ{<q>} <Rn>, <label>

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

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

  • CMP (immediate or register)

    • T1: CMP{<c>}{<q>} <Rn>, #<imm8>
    • T2: CMP{<c>}{<q>} <Rn>, #<const>
    • CMP{<c>}{<q>} <Rn>, <Rm>
    • CMP{<c>}{<q>} <Rn>, <Rm>, <shift_type> #<amount>

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

  • APSR中N,Z,C,V的含义
    在这里插入图片描述


三、位移指令

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

  • LSL
    在这里插入图片描述
    由伪代码可知,逻辑左移shift位之后,会在右边补shift位的0,并且会把最后左移出的位作为进位值

  • LSR
    在这里插入图片描述
    由伪代码可知,逻辑右移shift位之后,会在左边补shift位0,并将最后右移出的位作为进位值

  • ASR
    在这里插入图片描述
    由伪代码可知,算数右移shift位之后,会根据原本的符号位在左边补上shift个符号位,并将最后右移出的位作为进位值

  • ROR
    在这里插入图片描述
    由伪代码可知,循环右移shift位后,会将移除的数据放进左边,如果循环移位32次,那么这个数不会改变

  • RRX

在这里插入图片描述

四、位运算

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

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

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

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

五、待更新

总结

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

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值