一、ARM汇编
学习arm汇编的主要目的是为了编写arm启动代码,引导程序到c语言环境下运行。
启动代码的目的是为了在处理器复位以后搭建c语言最基本的需求。
启动代码的主要任务:
1、初始化异常向量表;
2、初始化各工作模式的栈指针寄存器;
3、开启arm内核中断允许;
4、将工作模式设置为user模式;
5、引导程序进入c语言主函数执行;
二、格式
伪操作
不是 ARM 处理器实际的指令(如 MOV, ADD 等),而是汇编器的命令,用于指导汇编器如何工作
area reset, code, readonly
code32
entry
end
area:用于定义一个段。程序、数据、堆栈等都需要被组织在不同的段中。
reset: 段的名字。名字 reset 具有很强的暗示性,通常用于表示复位向量段,即CPU上电或复位后首先执行的第一段代码所在的位置。
code: 指定该段的属性为代码,意味着这个段包含可执行的指令。
readonly: 指定该段的属性为只读。对于代码段来说,通常是默认且必须的。
code32: 表示后续指令使用 32位的 ARM 指令集。
thumb: 表示后续指令使用 16位的 Thumb 指令集。
三、指令
手册目录:指令(目的操作数,第一操作数,第二操作数)
immediate:立即数
register:寄存器
SP plus:栈指针
立即数:12位立即数imm12的条件是:
把某个数展开成2进制,该数必须存在一种循环右移(偶数位),使得移位后高24位全0,低8位即为有效imm8;
eg:0xA0 00 00 00 0A是立即数
0xFFFF FFFF 不是立即数
1. mov
手册484
基本格式:
MOV{S}<c> <Rd>, #<const>
MOV{S}<c> <Rd>, <Rm>
MOV与位移指令的结合:
注意:
(1)与C语言中的赋值运算对比(左值/右值),利于加深理解
(2)#<n>/<Rs> 取值范围 (0 - 31)
(3)RRX{S}:扩展右移 (不需要移位量)
(4)在计算机中只识别二进制数据,计算机没有有无符号,浮动点等概念
2. add
手册306
立即数作为第二操作数: ADD{S}<c> <Rd>, <Rn>, #<const>
寄存器作为第二操作数寄存器: ADD{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
寄存器作为第二操作数移位量: ADD{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
注意
(1){, <shift>} 其中{}代表可选择,“,”表示在使用时需要在Rm后添加“,” shift 移位量(立即数)
(2) add r0, #3, #2 :没有这种形式,C语言int a = 1 + 2; 编译阶段计算, 不需要在机器指令中体现
3. sub
手册708
立即数作为第二操作数: SUB{S}<c> <Rd>, <Rn>, #<const>
寄存器作为第二操作数寄存器: SUB{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
寄存器作为第二操作数移位量: SUB{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
4. ldr(加载指令)
手册406
LDR<c> <Rt>, <label>
5. sdr(存放指令)
6. mvn
手册504
MVN{S}<c> <Rd>, #<const>
MVN{S}<c> <Rd>, <Rm>{, <shift>}
MVN{S}<c> <Rd>, <Rm>, <type> <Rs>
7. bic
手册340
BIC{S}<c> <Rd>, <Rn>, #<const>
BIC{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
BIC{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
8. orr
手册516
ORR{S}<c> <Rd>, <Rn>, #<const>
ORR{S}<c> <Rd>, <Rn>, <Rm>{, <shift>}
ORR{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
9. 标志位
CPSR寄存器中条件判断标志位
N: 符号标志位:
上条指令执行结果最高位bit31为1,则 N = 1, 当结果作为有符号解释时为负值;
Z: 零值标志位:
上条指令执行结果为0(即bit0 - bit31 均为0),则 Z = 1;
C: 进位标志位:
进行无符号解读,如果在加法过程中进位或者减法时没有借位,则为 C = 1,否则 C = 0
V: 溢出标志位:
进行有符号解读,是否发生溢出 -2^31 - 2^31-1(两个正数加得负数,两个负数加得正数)
条件码: eq(相等) ne(不相等)
ge(大于等于) gt(大于) le(小于等于) lt(小于)
al(无条件执行)
10. cmp
手册370
CMP<c> <Rn>, #<const>
CMP<c> <Rn>, <Rm>{, <shift>}
CMP<c> <Rn>, <Rm>, <type> <Rs>
比较并获取三个数中的最大值
11. b bl bx
手册334
B<c> <label>
b fun <==> ldr pc, =fun
直接跳转到目标地址,不保存返回地址
BL<c> <label>
bl fun
跳转前将返回地址存入LR寄存器
BX<c> <Rm>
bx lr <==> mov pc, lr
跳转到寄存器指定的地址,并可切换指令集,不保存返回地址
12. while / do while
循环三要素
循环结束条件
推动循环趋向终结的语句
循环的循环体
while实现0 -100 求和
do while 实现0 -100 求和
13. function
四、ARM栈
FD (满减栈)
栈指针(SP)指向最后压入的元素,即栈顶元素
操作方式:PUSH:SP先减少再存数据
POP: 先取数据再增加SP
FA(满增栈)
栈指针(SP)指向最后压入的元素,即栈顶元素
操作方式:PUSH:SP先增加再存数据
POP: 先取数据再减少SP
EA (空增栈)
栈指针(SP)指向下一个空闲位置
操作方式:PUSH:现存数据再增加SP
POP: SP先减少再取数据
ED (空减栈)
栈指针(SP)指向下一个空闲位置
操作方式:PUSH:现存数据再减少SP
POP: SP先增加再取数据