一、指令,伪指令
指令:cpu机器指令的助记符
伪指令:本质不是指令,编译器环境提供,目的是指导编译过程,不会生成机器码
二、汇编特点
2.1、LDR/STR
ARM采用RISC架构,CPU本身不能直接读取内存,需要先将内存加载到寄存器才能CPU处理。
ldr:将内存加载到通用寄存器
str:将通用寄存器内容存入到内存
LDR r0,[r1]
LDR R0, =__main //伪指令
2.2、8种寻址方式
寄存器寻址:mov r1,r2 r1=r2;
立即寻址:mov r0,#0xff00
寄存器移位寻址:mov r0,r1,lsl #3
寄存器间接寻址:ldr r1,[r2]
基址变址寻址:ldr r1,[r2,#4]
多寄存器寻址:ldmia r1!,[r2-r7,r12]
堆栈寻找:stmfd sp!,[r2-r7,lr]
相对寻址:flag:
2.3、指令后缀
B:功能不变,操作长度变为8位
H:功能不变,长度16位
S:功能不变,操作数变为有符合。 如:ldr ldrb ldrh ldrsb ldrsh
S:功能不变,影响CPSR标志位。如:MOV和MOVS movs r0,#0
2.4、条件执行后缀
1、条件后缀执行是否成立,不是取决于本句代码,而是取决于这句代码之前的代码运行后的结果
2、条件后缀只是决定本句代码是否执行,并不影响下一句代码
EQ,NE等
moveq r1,r2 类似c语言:if(eq){r1=r2;}
2.5、多级指令流水线
取指令--------->译码------------>执行
三、汇编指令
3.1、数据处理指令
数据传输指令:mov mvn
算术指令:add sub rsb adc sbc rsc
逻辑指令:and orr eor bic
比较指令:cmp cmn tst teq
乘法指令:mvl mla umull umlal smull smlal
前导零计数:clz
3.2、cpsr访问指令
mrs:读psr
msr:写psr
3.3、跳转指令
b:直接跳转
bl:跳转前把地址放入lr寄存器,用于函数调用
bx:跳转同时切换到ARM模式,用于异常处理
3.4、访存指令
单字/半字/字节访问:ldr/str
多字批量访问:ldm/stm
swp
ldmia r0!,{r2-r3} !作用:就是r0值在ldm过程中发生增加减少最后写回到r0,也就是ldm时会改变r0值。
ldmfd sp!,{r0-r6,pc} ^ ^作用:在目标寄存器有pc时,会同时将spsr写入cpsr,用于异常模式返回
8种后缀
ia 先传输,再地址+4
ib 先地址+4,再传输
da 先传输,再地址-4
db 先地址-4,再传输
fd 满递减堆栈
ed 空递减堆栈
fa 满递增堆栈
ea 空递增堆栈
四种栈
空栈,满栈,增栈,减栈
3.5、软中断指令
swi :用来实现操作系统的系统调用
3.6、cp15操作指令
mrc:读取cp15中的寄存器
mcr:写入cp15中的寄存器
四、协处理器
协助主cpu实现某些功能
ARM设计上支持多达16个协处理器,但是一般soc只实现其中的cp15
协处理器和MMU,cache,TLB等处理有关,功能上和操作系统的虚拟地址映射,cache管理等有关
例如:
mrc p15,0,r0,c1,c0,0
orr r0,r0,#1
mcr p15,0,r0,c1,c0,0
五、伪指令
gnu汇编符号
@注释
:结尾标号
. 当前指令地址
立即数
@c语言的死循环 while(1);
flag:
b flag
b .
@2种死循环
gnu伪指令
.global _start @给_start外部链接属性,相当于extern
.section .text @指定当前段为代码段
.ascii .byte .short .long .word .quad .float .string @定义数据
.align 4 @以16字节对齐
.balignl 16 0xabcdefgh @以16字节对齐填充
.equ @类似c宏定义
.end @标识文件结束
.include @ 头文件包含
.arm / .code32 @声明以下为arm指令
.thumb / .code16 @声明以下为thubm指令
AAA:
.word 0xabcdef
@等价于 unsigned int AAA = 0xabcdef;
最重要的几个伪指令
ldr 大范围的地址加载指令
adr 小范围的地址加载指令
adrl 中等范围的地址加载指令
nop 空操作
@adr,ldr区别
ldr加载的地址在链接时确定,而adr加载的地址在运行时确定
我们可以通过adr和ldr加载的地址比较来判断当前程序是否在链接时指定的地址运行