ARM汇编指令总结


目的

总结目的是为了看懂ARM返汇编程序含义。如果是抱着来看这篇blog的盆友,希望可以帮到你们;如果有错误,请多指出。谢谢!


#

ARM指令的一般格式

arm指令字长为固定的32位。一条典型的arm指令编码格式如下:

一条典型的ARM指令语法格式如下所示:

参数
opcode:指令操作符编码

cond:决定指令的操作是否影响CPSR的值

S:决定指令操作是否影响CPSR的值

Rd:目标寄存器编码

Rn:包含第1个操作数的寄存器编码

shifter_operand表示第2个操作数


汇编指令执行条件

大多数ARM指令都可以条件执行,即根据cpsr寄存器中的条件标志位决定是否执行该指令:如果条件不满足,该指令相当于一条nop执行。

每条ARM指令包含4位条件码域,这表明可以定义16个执行条件。这16个条件码和他们的助记符(标记)如下:


操作数的运算处理方式

一共有下面9种格式:

  • [< Rn>, #+/-]
  • [< Rn>, +/-< Rm>]
  • [< Rn>, +/-< Rm>, < shift>#]
  • [< Rn>, #+/-]!
  • [< Rn>, +/-< Rm>]!
  • [< Rn>, +/-< Rm>, < shift>#]!
  • [< Rn>], #+/-
  • [< Rn>], +/-< Rm>
  • [< Rn>], +/-< Rm>, < shift>#

总结一下我们可以对上面格式分类:例如:1~3为一类,4~6为一类,7~9为一类。同样的,我们也可以这样分类:1,4,7为一类,2,5,8为一类,3,6,9为一类。

例子示范

通过举例子来说明各个类型的意义。

----------------[< Rn>, #+/-<offset_12>]:---------------LDR R0,[R1, #4] //将内存单元R1+4中的字读取到R0寄存器中。-------------------[< Rn>, +/-< Rm>]:-------------------
LDR R0,[R1,R2]      //将内存单元R1+R2中的字读取到R0寄存器中----------[< Rn>, +/-< Rm>, < shift>#<offset_imm>]------
LDR R0,[R1,R2, LSL #2]  //将地址单元{R1+R2*4}中的数据读取到R0中-----------------[< Rn>, #+/-<offset_12>]!--------------
LDR R0,[R1, #4]     //将内存单元R1+4中的字读取到R0寄存器中//同时R1=R1+4---------------------[< Rn>, +/-< Rm>]!-----------------
LDR R0,[R1, R2]!    //将内存单元(R1, R2)中的字读取到R0寄存器中//同时R1=R1+R2---------[< Rn>, +/-< Rm>, < shift>#<offset_imm>]!------
LDR R0,[R1, R2, LSL #2]!    //将内存单元(R1+R2*4)中的数据读取到R0寄存器中//同时R1=R1+R2*4------------------[< Rn>], #+/-<offset_12>--------------
LDR R0, [R1], #4    //将地址为R1的内存单元数据读取到R0中//然后R1=R1+4----------------------[< Rn>], +/-< Rm>-----------------
LDR R0, [R1], R2    //将地址为R1的内存单元数据读取到R0中//然后R1=R1+R2---------[< Rn>], +/-< Rm>, < shift>#<offset_imm>-------
LDR R0, [R1], R2, LSL #2    //将地址为R1的内存单元数据读取到R0中//然后R1=R1+R2*4          

CPRS各位介绍

CPRS为状态寄存器,下面他各位的功能和代表的含义

.word

.word expression就是在当前位置放一个word型的值,这个值就是expression

例子示范

_rWTCON:
.word 0x15300000
//就是在当前地址,即_rWTCON处放一个值0x15300000 

.macro

宏定义

参数

宏名称 .MACRO [形式参数]........宏定义语句.........ENDM

例子示范

SWAP_REG   .MACRO   REG1,REG2   ; swap registersXCH   A, REG1XCH   A, REG2XCH   A, REG1.ENDM

.global

告诉编译器后续跟的是一个全局可见的名字[可能是变量,也可以是函数名]

.type

.type:用来指定一个符号的类型是函数类型或者是对象类型, 对象类型一般是数据, 格式如下:
.type 符号, 类型描述

@

这个是 GNU 汇编的规范. 就是注释.

A


add

加指令

例子示范

add r1,r2,#1    //表示r1=r2+1, 即寄存器r1的值等于寄存器r2的值加上1

adr和adrl

adr伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。adrl伪指令比adr伪指令可以读取更大范围的地址,其他功能一样。

参数

ADR伪指令格式 :ADR{cond}  register, expr
ADRL伪指令格式:ADRL{cond}  register, expr

例子示范

adr    r2, mem_cfg_val  //存储相对位置
adr    r1, mem_cfg_val  //存储相对位置mem_cfg_val:...

align

.align的作用在于对指令或者数据的存放地址进行对齐,有些CPU架构要求固定的指令长度并且存放地址相对于2的幂指数圆整,否则程序无法正常运行,比如ARM。

参考:
http://blog.csdn.net/xingyu19871124/article/details/7333622


B


b和bl

相对跳转指令。两条指令不同之处在于bl指令除了跳转之外,还将返回地址(bl的下一条指定的地址)保存在lr寄存器中。

例子示范

b fun1fun1:.....

bic

bic(位清除)指令对 Rn 中的值 和 Operand2 值的反码按位进行逻辑“与”运算

BIC    R1,  R1,   #0x0F
#将R1   低4位清0

C


D


E


equ

equ是类似于宏的作用,相当于#define。

例子示范

.equ        MEM_CTL_BASE,       0x48000000

F


G


H


I


J


K


L


long

.long:定义4字节数据,

例子示范

.long 0x12345678,23876565

ldr

这个指令是一个伪指令,他不是真实存在的指令,编辑器会把它扩展成真正的指令。

ldr指令从内存中读取数据到寄存器。

例子示范

ldr r1,=4096    //r1 = 4096ldr r1,[r2,#4]  //将地址为r2+4的内存单元数据读取到r1中去
ldr r1,[r2]     //将地址为r2的内存单元位数据读取到r1中去
ldr r1,[r2],#4  //将地址为r2的内存单元的数据读取到r1中,然后r2=r2+4

ldm

ldm{cond} {!} < register list> {^}

批量访问内存,内存中批量读取数据到寄存器。从< rn> 对应的内存块中取出数据,写入 < register list>这些寄存器。

参数

  • {cond}表示指定执行条件

  • 表示内存变化的模式:

    1. ia(increment after):事后递增方式
    2. ib(increment before):事先递增方式
    3. da(decrement after):事后递减方式
    4. db(decrement before):事先递减方式
  • < rn>中保存着内存的地址,
  • {!}加上了感叹号,指令执行后,rn的值会更新,等于下一个内存单元地址。
  • < register list>表示寄存器列表,指令中寄存器列表和内存单元对应关系为:编号低得寄存器对应内存中得低地址单元,编号高的寄存器对应内存中的高地址单元。
  • {^}有两个含义:如果< register list>中有pc寄存器,它表示指令执行之后,spsr寄存器的值将自动复制到cpsr寄存器中–这常用于从中断处理函数中返回;如果< register list>中没有pc寄存器,{^}表示操作的是用户模式下的寄存器,而不是当前特权模式的寄存器。

例子示范

ldmia sp!,{r0-r12,pc}//中断返回,“^”表示将spsr的值复制到cpsr
//于是从irq模式返回被中断的工作模式
//“!”使得指令执行后,sp=sp+14*4

M


mov

mov指令可以把一个寄存器的值赋给另一个寄存器,或者把一个常数赋值给寄存器。

例子示范

mov r1,r2   //r1 = r2
mov r1,#4096    //r1 = 4096

msr和mrs

程序状态寄存器访问指令。

ARM处理器中有一个程序状态寄存器(cpsr),他用来控制处理器的工作模式,设置中断的总开关。

例子示范

msr cpsr,r0 //复制r0到cpsr中
mrs r0,cpsr //复制cpsr到r0中

mcr和mrc

MCR指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。

MRC指令将协处理器的寄存器中数值传送到ARM处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。

格式

MCR{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}MRC{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}

参数

  1. 为指令执行的条件码。当忽略时指令为无条件执行。MCR2中,为Ob1111,指令为无条件执行指令。

  2. 为协处理器将执行的操作的操作码。对于CP15协处理器来说, 永远为0b000,当不为0b000时,该指令操作结果不可预知。

  3. 作为元寄存器的ARM寄存器,其值被传送到得协处理器寄存器中。

  4. 不能为PC,当其为PC时,指令操作结果不可预知。

  5. 作为目标寄存器的协处理器寄存器,其编号可能为C0,C1….C15。 附加的目标寄存器或者原操作数寄存器,用于区分同一个编号的不同物理寄存器。当指令中不需要提供附加信息时,将C0指定为,否则指令操作结果不可预知。

  6. 提供附加信息,用于区别同一个编号的不同物理寄存器。当指令中指定附加信息时,省略或者将其指定为0,否则指令操作结果不可预知。


N


O


P


Q


R


S


str

str也是一条伪指令。str指令把寄存器的值存储到内存中。

例子示范

str r1,[r2,#4]  //将r1的数据保存到地址为r2+4的内存单元中
str r1,[r2]     //将r1的数据保存到地址为r2的内存单元中
str r1,[r2],#4  //将r1的数据保存到地址为r2的内存单元中,然后r2=r2+4

stm

stm{cond} {!} < register list> {^}

批量存储数据到内存,寄存器批量存储数据到内存。< register list>这些寄存器中得数据,批量写入到< rn> 对应的内存块中。

参数

  • {cond}表示指定执行条件

  • 表示内存变化的模式:

    1. ia(increment after):事后递增方式
    2. ib(increment before):事先递增方式
    3. da(decrement after):事后递减方式
    4. db(decrement before):事先递减方式
  • < rn>中保存着内存的地址,
  • {!}加上了感叹号,指令执行后,rn的值会更新,等于下一个内存单元地址。
  • < register list>表示寄存器列表,指令中寄存器列表和内存单元对应关系为:编号低得寄存器对应内存中得低地址单元,编号高的寄存器对应内存中的高地址单元。
  • {^}有两个含义:如果< register list>中有pc寄存器,它表示指令执行之后,spsr寄存器的值将自动复制到cpsr寄存器中–这常用于从中断处理函数中返回;如果< register list>中没有pc寄存器,{^}表示操作的是用户模式下的寄存器,而不是当前特权模式的寄存器。

例子示范

stmdb sp!,{r0-r12,lr}//保存使用到得寄存器
//r0-r12,lr被保存在sp表示的内存中
//“!”使得指令执行后sp=sp-14*4

sub

减指令

例子示范

sub r1,r2,#1    //表示r1=r2-1

T


U


V


W


X


Y


Z

汇编语言--ARM汇编相关推荐

  1. 【Android 逆向】arm 汇编 ( 使用 IDA 解析 arm 架构的动态库文件 | 分析 malloc 函数的 arm 汇编语言 )

    文章目录 一.分析 malloc 函数的 arm 汇编语言 一.分析 malloc 函数的 arm 汇编语言 在上一篇博客 [Android 逆向]arm 汇编 ( 使用 IDA 解析 arm 架构的 ...

  2. ARM汇编:使用汇编语言进行数据访问时需要注意的几个问题

     ARM汇编:使用汇编语言进行数据访问时需要注意的几个问题

  3. 经常使用ARM汇编指令

    一面学习,一面总结,一面记录. 以下是整理在网上找到的一些资料,简单整理记录一下,方便以后查阅. ARM处理器的指令集能够分为跳转指令.数据处理指令.程序状态寄存器(PSR)处理指令.载入/存储指令. ...

  4. GNU ARM汇编--(二)汇编编译链接与运行

    GNU的汇编器是GNU Tools的一部分,可以用来ARM的汇编语言源代码编译为二进制文件.关于GNU汇编器的介绍可以搜索<GNU Assembler Manual>.这里我们只是做一个简 ...

  5. 【嵌入式开发】 ARM 汇编 (指令分类 | 伪指令 | 协处理器访问指令)

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42408137  转载请著名出处 本博客相关文档下载 :  -- A ...

  6. ARM汇编 beq和bne

    1. 前阵子看cpu从sleep模式唤醒时,对tst bne和tst beq有些模糊.先记录: 摘抄如下: TST     R0, #0X8 BNE    SuspendUp :BNE指令是" ...

  7. ARM汇编基础详解(PS学习汇编的原因)

    目录 前言 1.GNU 汇编语法 2.Cortex-A7 常用汇编指令 2.1 处理器内部数据传输指令(内部寄存器数据非内存数据) 2.2 存储器访问指令(RAM) 2.3 压栈和出栈指令(了解) 2 ...

  8. ARM 汇编学习——编写简单的ARM汇编程序

    首先,我们先看一个简单的汇编程序: [plain] view plaincopy area ff,code,readonly   :声明代码段 code32  :声明为32位ARM指令 entry   ...

  9. ARM 汇编基础教程番外篇 ——配置实验环境

    From:https://zhuanlan.zhihu.com/p/29145513 win10 arm 汇编环境 Windows 平台下搭建 ARM 汇编集成环境:https://jingyan.b ...

最新文章

  1. Mysql依赖库Boost的源码安装,linux下boost库的安装
  2. 使用Global.asax在ASP.NET中记录错误日志
  3. leetcode每日刷题计划-简单篇day8
  4. 选择排序之——堆排序(c/c++)
  5. 关于STM32中CAN1_RX0_IRQn和CAN1_RX1_IRQn的使用
  6. Delphi中字符串比较大小 VS Oracle-SQL中字符串比较大小
  7. WeChatTweak-微信小助手安装教程
  8. JVM——Java内存模型(JMM)
  9. ASP.NET2.0中themes、Skins轻松实现网站换肤!
  10. 19.Qt中Thread线程中创建QTcpSocket
  11. [转贴] PHP 编程标准
  12. Python—什么是duck type鸭子类型
  13. 你是如何看待 ‘裸辞’ 这件事的?
  14. cmd echo写入shell_为什么说Shell脚本就是最好的教程和笔记呢?
  15. 服务器虚拟机要怎么安装,服务器虚拟机怎么安装
  16. 【ProCAST】铸件定向凝固仿真流程学习总结
  17. 标准误计算机excel公式,关于excel计算标准差SD和标准误SE的方法
  18. 安卓玩机教程---全机型安卓4----安卓12 框架xp edx lsp安装方法
  19. Java基础回顾--jav集合1 集合的分类、解析
  20. 网络安全-Web端安全协议

热门文章

  1. 通过git上传的文件在服务器端哪里_本地文件上传gitlab服务器
  2. html怎么添加背景图片
  3. 2022年大数据开发实习面经总结,已拿顺丰、哔哩哔哩offer
  4. 分形插值matlab,分形插值算法和MATLAB实验
  5. 网易游戏如何做到不停服维护?
  6. 根据学生分数给学生成绩分等级
  7. bt云服务器地址,windows服务器使用BT搭建环境
  8. 魅族手机刷linux系统下载,把Ubuntu版魅族PRO 5刷成安卓系统
  9. 分享146个ASP源码,总有一款适合您
  10. 基于FPGA实现的流水灯项目