一、两个概念:指令与伪指令
- (汇编)指令,是 CPU 机器指令的助记符,经过编译后会得到一串10组成的机器码,可以由 CPU 读取执行。
- (汇编)伪指令,本质上不是指令(只是和指令一起写在代码中),它是编译器环境提供的,目的是用来指导编译过程,经过编译后伪指令最终不会生成机器码。
二、两种不同风格的 ARM 指令
- ARM 官方的 ARM 汇编风格:指令一般用大写、Windows 中 IDE 开发环境(如 ADS、MDK 等)常用。如: LDR R0, [R1]
- GNU 风格的 ARM 汇编:指令一般用小写字母、linux 中常用。如:ldr r0, [r1]
注意:
- 汇编指令对应于 CPU 执行的机器码,不管是 Windows 风格,还是 GNU 风格,都是一样的(只是大小写区别);
- 伪指令属于编译环境的一部分,取决于编译环境。因此 Windows 风格和 GNU 风格的伪指令,是完全不同的;
三、ARM 汇编特点
汇编特点1:LDR/STR架构
- ARM 采用 RISC 架构,CPU 本身不能直接读取内存,而需要先将内存中内容加载入 CPU 中的通用寄存器中,才能被 CPU 处理。
- ldr(load register)指令将
内存内容
加载入通用寄存器
。 - str(store register)指令将
寄存器内容
存入内存空间
中。 - ldr/str 组合用来实现 ARM CPU 和内存数据的交换。
汇编特点2:8 种寻址方式
mov 指令的操作数,是寄存器与寄存器之间
- 寄存器寻址 mov r1, r2
- 立即寻址 mov r0, #0xFF00
- 寄存器移位寻址 mov r0, r1, lsl #3
ld,st 指令的操作数,是寄存器与内存空间之间
- 寄存器间接寻址 ldr r1, [r2] @ r2代表内存空间的地址
- 基址变址寻址 ldr r1, [r2, #4] @ r2 + 4 ,代表内存空间的地址
- 多寄存器寻址 ldmia r1!, {r2-r7, r12} @ r1 保存的内存地址作为起始地址, 相当于一个数组,将数组的值存放到{r2-r7, r12} 6 个寄存器组当中
- 堆栈寻址 stmfd sp!, {r2-r7, lr} @ 同上,将 sp 寄存器保存的内存地址开始,连续取出内存内容,放到 {r2-r7, lr} 寄存器组当中
- 相对寻址 beq flag
flag:
其中flag:
是标号,相当于 C语言中 goto 语句将要跳转到的标号位置。
汇编特点3:指令后缀
同一指令经常附带不同后缀,变成不同的指令。经常使用的后缀有:
-
B(byte)功能不变,操作长度变为8位;
-
H(half word)功能不变,长度变为16位;
ARM 汇编默认是 32 bit 指令,默认处理的也是 32 bit 数据。当你一次不想处理 32 bit 数据,就可以使用 B 或者 H,如:ldr ldrb ldrh。
-
S(signed)功能不变,操作数变为有符号;
如 ldrsb ldrsh。 -
S(S标志)功能不变,影响CPSR标志位;
如 mov 和 movs movs r0, #0
汇编特点4:条件执行后缀
mov r0, r1 @ 相当于C语言中的r0 = r1;
moveq r0, r1 @ 如果eq后缀成立,则直接执行mov r0, r1;如果eq不成立则本句代码直接作废,相当于没有
@ 类似于C语言中 if (eq){r0 = r1;}
条件后缀执行注意2点:
1、条件后缀是否成立,不是取决于本句代码,而是取决于这句代码之前的代码运行后的结果。
2、条件后缀决定了本句代码是否被执行,而不会影响上一句和下一句代码是否被执行。
ARM汇编特点 5:多级指令流水线
- 为增加处理器指令流的速度,ARM 使用多级流水线.,下图为 3 级流水线工作原理示意图。(S5PV210 使用13 级流水线,ARM11 为 8 级)
- 允许多个操作同时处理,而非顺序执行。
PC
指向正被取指的指令
,而非正在执行的指令
B站朱友鹏老师.