汇编语言--ARM汇编
2015-12-09 19:30
295 查看
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为一类。
例子示范
通过举例子来说明各个类型的意义。
[code]----------------[< 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例子示范
[code]_rWTCON: .word 0x15300000 //就是在当前地址,即_rWTCON处放一个值0x15300000
.macro
宏定义参数
[code]宏名称 .MACRO [形式参数] ........ 宏定义语句 ........ .ENDM
例子示范
[code]SWAP_REG .MACRO REG1,REG2 ; swap registers XCH A, REG1 XCH A, REG2 XCH A, REG1 .ENDM
.global
告诉编译器后续跟的是一个全局可见的名字[可能是变量,也可以是函数名].type
.type:用来指定一个符号的类型是函数类型或者是对象类型, 对象类型一般是数据, 格式如下:.type 符号, 类型描述
@
这个是 GNU 汇编的规范. 就是注释.A
add
加指令例子示范
[code]add r1,r2,#1 //表示r1=r2+1, 即寄存器r1的值等于寄存器r2的值加上1
adr和adrl
adr伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。adrl伪指令比adr伪指令可以读取更大范围的地址,其他功能一样。参数
[code]ADR伪指令格式 :ADR{cond} register, expr ADRL伪指令格式:ADRL{cond} register, expr
例子示范
[code]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寄存器中。例子示范
[code]b fun1 fun1: .....
bic
bic(位清除)指令对 Rn 中的值 和 Operand2 值的反码按位进行逻辑“与”运算[code]BIC R1, R1, #0x0F #将R1 低4位清0
C
D
E
equ
equ是类似于宏的作用,相当于#define。例子示范
[code].equ MEM_CTL_BASE, 0x48000000
F
G
H
I
J
K
L
long
.long:定义4字节数据,例子示范
[code].long 0x12345678,23876565
ldr
这个指令是一个伪指令,他不是真实存在的指令,编辑器会把它扩展成真正的指令。ldr指令从内存中读取数据到寄存器。
例子示范
[code]ldr r1,=4096 //r1 = 4096 ldr 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}表示指定执行条件
表示内存变化的模式:
ia(increment after):事后递增方式
ib(increment before):事先递增方式
da(decrement after):事后递减方式
db(decrement before):事先递减方式
< rn>中保存着内存的地址,
{!}加上了感叹号,指令执行后,rn的值会更新,等于下一个内存单元地址。
< register list>表示寄存器列表,指令中寄存器列表和内存单元对应关系为:编号低得寄存器对应内存中得低地址单元,编号高的寄存器对应内存中的高地址单元。
{^}有两个含义:如果< register list>中有pc寄存器,它表示指令执行之后,spsr寄存器的值将自动复制到cpsr寄存器中–这常用于从中断处理函数中返回;如果< register list>中没有pc寄存器,{^}表示操作的是用户模式下的寄存器,而不是当前特权模式的寄存器。
例子示范
[code]ldmia sp!,{r0-r12,pc} //中断返回,“^”表示将spsr的值复制到cpsr //于是从irq模式返回被中断的工作模式 //“!”使得指令执行后,sp=sp+14*4
M
mov
mov指令可以把一个寄存器的值赋给另一个寄存器,或者把一个常数赋值给寄存器。例子示范
[code]mov r1,r2 //r1 = r2 mov r1,#4096 //r1 = 4096
msr和mrs
程序状态寄存器访问指令。ARM处理器中有一个程序状态寄存器(cpsr),他用来控制处理器的工作模式,设置中断的总开关。
例子示范
[code]msr cpsr,r0 //复制r0到cpsr中 mrs r0,cpsr //复制cpsr到r0中
mcr和mrc
MCR指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。MRC指令将协处理器的寄存器中数值传送到ARM处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。
格式
[code]MCR{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>} MRC{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}
参数
为指令执行的条件码。当忽略时指令为无条件执行。MCR2中,为Ob1111,指令为无条件执行指令。
为协处理器将执行的操作的操作码。对于CP15协处理器来说, 永远为0b000,当不为0b000时,该指令操作结果不可预知。
作为元寄存器的ARM寄存器,其值被传送到得协处理器寄存器中。
不能为PC,当其为PC时,指令操作结果不可预知。
作为目标寄存器的协处理器寄存器,其编号可能为C0,C1….C15。 附加的目标寄存器或者原操作数寄存器,用于区分同一个编号的不同物理寄存器。当指令中不需要提供附加信息时,将C0指定为,否则指令操作结果不可预知。
提供附加信息,用于区别同一个编号的不同物理寄存器。当指令中指定附加信息时,省略或者将其指定为0,否则指令操作结果不可预知。
N
O
P
Q
R
S
str
str也是一条伪指令。str指令把寄存器的值存储到内存中。例子示范
[code]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}表示指定执行条件
表示内存变化的模式:
ia(increment after):事后递增方式
ib(increment before):事先递增方式
da(decrement after):事后递减方式
db(decrement before):事先递减方式
< rn>中保存着内存的地址,
{!}加上了感叹号,指令执行后,rn的值会更新,等于下一个内存单元地址。
< register list>表示寄存器列表,指令中寄存器列表和内存单元对应关系为:编号低得寄存器对应内存中得低地址单元,编号高的寄存器对应内存中的高地址单元。
{^}有两个含义:如果< register list>中有pc寄存器,它表示指令执行之后,spsr寄存器的值将自动复制到cpsr寄存器中–这常用于从中断处理函数中返回;如果< register list>中没有pc寄存器,{^}表示操作的是用户模式下的寄存器,而不是当前特权模式的寄存器。
例子示范
[code]stmdb sp!,{r0-r12,lr} //保存使用到得寄存器 //r0-r12,lr被保存在sp表示的内存中 //“!”使得指令执行后sp=sp-14*4
sub
减指令例子示范
[code]sub r1,r2,#1 //表示r1=r2-1
T
U
V
W
X
Y
Z
相关文章推荐
- ODBC、OLE DB、 ADO的区别
- 【STL】滤波算法:使用vector容器
- android 显示 PDF 文件
- TeamToy - 创新团队的效率工具 一个好用的 团队协作软件
- 运维监控——zabbix环境的搭建配置
- 树形结构(一)
- Address already in use: JVM_Bind <null>:8080
- Android ViewPager实现无限循环滑动
- 【网络流量最大流量】poj3281Dining
- 安卓开发如何提高Android程序的效率(转)
- ios 数组里面的字典,
- linux: Ubuntu安装samba的问题
- Spring-jdbc-事务处理详解及案例<五>
- 关于头文件中为什么定义的变量用extern关键字
- USB core(二) - root_hub设备和usb device设备
- play2在scala中创建函数和变量
- error C2143: syntax error : missing ';' before 'namespace'
- 继承的简单实现
- 读书笔记-命令行总结
- java数据结构系列——排列(2):有序阵列