,
ARM汇编指令集:
指令:汇编指令是CPU机器指令的助记符号,编译后得到一系列由1、0组成的机器代码,CPU可以读取执行
伪指令:在编译过程中发挥作用,指导编译过程,编译后不生成机器码
***ARM部件的特点1:LDR/STR体系结构: RISC体系结构要求cpu通过cpu内部的寄存器才能读写内存。 (CISC的cpu可以直接与内存通信。 )
***ARM程序集特征2:8中的寻址方式
#寄存器地址mov r1、r2将r2的内容发送到r1中()寄存器按名称查找) )。
#即时寻址(即时数) mov r0、#0xFF00加#表示数字
#寄存器移位地址mov r0、r1、lsl #3 lsl左移命令将r1的值向左移动3位,并将左移后生成的随机数代入r0
#寄存器间地址ldr r1、[r2] [r2]表示存储器地址不存在于r2,将存储在存储器地址中的值分配给r1
索引修饰ldr r1,[r2,#4]
[r2,#4]中存储的地址是由r2中存储的地址4构成的地址,r2中存储的地址称为基地址,后续的数字的意思是所需的索引数。 将存储在r2中的存储器地址加上4后的地址的值代入r1
#多寄存器地址ldmia r1!{r2-r7,r12}
一次访问多个寄存器//r1中的存储器地址,排列r1,r2-r7、r12表示7个寄存器,
指令的意思是以存储在r1中的存储器地址作为基地址,并且从该地址开始顺序将存储在七个连续地址中的值存储在后续的相应寄存器中
#堆栈地址stmfd sp!{r2-r7,lr}
#相对寻址beq标志
(标志)标签
***ARM汇编的特点3 :指令后缀
同一指令往往带有不同的后缀,成为不同的指令。 常用的后缀如下:
b (字节)功能不变。 操作长度为8位
h (半工作区)功能保持不变。 长度将为16位
s (签名)功能不变。 操作数是带符号的
例如ldr ldrb ldrh ldrsb ldrsh
s(s标志)功能不变,影响CPSR标志的位一般用于数据传输指令
例如mov和movs movs r0、#0
***ARM程序集的特点4 :条件执行后缀
mov r0,r1 @相当于c语言的r0=r1
如果moveq r0、r1@eq后缀成立,则执行该语句的命令,否则不执行
后缀执行注意事项:
1 .条件后缀是否成立取决于执行此代码前面的代码后的结果,而不是此语句的代码
2 .条件后缀决定是否执行此语句的代码,而不是上一语句或下一语句的代码是否执行
***ARM汇编的特点5 :多级指令流水线
pc是指指示的命令,而不是正在运行的命令
******数据传输命令
在mov r1、r0 @个寄存器之间传送数据
mov r1,#12fff @将即时数分配给目标寄存器
其区别在于,mvn和mov一样直接传递mov,mvn以比特为单位反向传递
***逻辑指令
与逻辑积
或逻辑
eor异或
bic比特清除指令bic r0、r1、#0x1f从r1中的多个bit0中清除bit4(#0X1F为1的比特清除),并代入r0
***比较命令
cmp
cmn看两个值是否互补
tst test r0,#0xf @测试r0的0~3位是否为0
teq测试是等效的
比较指令用于比较两个寄存器的数量
比较指令可以在后面不加s后缀就影响cpsr的标志位
******常用ARM命令
CSR访问指令: mrs msr
mrs用于读取psr,msr用于写psr
CSR寄存器是特殊的,需要特殊的指令访问。 这就是mrs和msr
***跳跃命令
b bl bx
b:直接跳
bl(branchandlink ) :在跳转之前将返回地址放入lr中,返回并用于函数调用
*******访问命令
ldr /str/ldm/stm/swp
1字/半字/字节访问: ldr/str
多字批量访问: ldm/stm
swp:内存和寄存器交换指令
swp r1、r2、[r0]将r0存储的地址的内容保存在r1中,将r2的内容保存在r0存储的地址的存储器中
swp r1,r1,[r0]
* * * * * * * * * * * * * *
合法即时数和非法即时数
除命令标记外,ARM命令为32位
和操作标记外,本身只能附带很少位数的立即数。因此立即数有合法和非法之分。合法立即数:经过任意位数的移位后非零部分可以用8位表示的即为合法立即数
**************
协处理器cp15的操作指令
mcr& mrc
mrc用于读取cp15中的寄存器
mcr用于写入cp15中的寄存器
*******************
由于ldr/str每周期只能访问4字节内存,如果需要批量读取,写入内存时太慢,解决的方案就是ldm/stm
ldm/stm与栈的处理
ldm (load register mutiple)
stm (store register mutiple)
****************************************************************
!的作用:r0值在ldm过程中发生的增加或减少写回到r0去,也就是ldm在运算过程中会改变r0中的地址值,如果没有!,则r0中的地址值不发生变化,如果有!,则r0中的值,会发生相应的改变
ldmia r0,{r2,r3}
ldmia r0!,{r2,r3}
^的作用:在目标寄存器中有PC时,会同时将spsr写入到cpsr(异常返回的时候)
ldmfd sp!,{r0-r6,pc}
ldmfd sp!,{r0-r6,pc}^
四种栈
空栈: 空栈就是当需要往栈中加入内容的时候,直接将内容存入栈指针所指向的地址空间,然后在将栈指针指向下一个空的地址空间,而要取出内容时则需要先移动指针才能去除
满栈: 满栈就是栈指针始终指向栈的最后一格,每次需要存储内容时,都需要先移动栈指针,然后把你内容存入栈指针所指向的地址空间,当要取出内容的时候不用移动指针直接可以取出
增栈 栈指针移动的时候,往地址值增加的方向移动
减栈 栈指针移动的时候,往地址值减小的方向移动
**********************************************************
伪指令
@用来做注释
#做注释一般用来放做行首,表示这一行都是注释而不是代码
:以冒号结尾的是标号
.点号 在gnu汇编中表示当前指令的地址
立即数前面要加#或者$,表示这个数是立即数