目录
一、ARM寄存器
二、ARM基本指令
三、寄存器寻址方式
四、程序中函数的实现—调用过程
1、汇编语言是CPU执行效率最高的一门语言,一条汇编指令是唯一对应一条机器指令(二进制码)。
2、ARM汇编语言是一门低级语言,它与系统的底层打交道,直接访问底层硬件资源。
3、寄存器是CPU的组成部分,是和存储器交互的桥梁,它们可用来暂存指令、数据和地址。
ARM寄存器分为2类,通用寄存器和状态寄存器。通用寄存器总共16种,分别为R0到R15;状态寄存器共2种,分别为CPSR和SPSR。
16种通用寄存器:(总个数31)
R15 别名PC(program counter)程序计数器:保存当前正在执行的指令在内存中的地址,当指令执行结束后,PC的值自动+1,即自动指向下一条即将执行的指令在内存中的位置。因为当程序通过汇编指令完成了对PC寄存器的赋值操作的时候,其实就是完成了一次无条件跳转。
R14 别名LR(linked register)链接寄存器:用于存放子程序的返回地址,它是ARM程序实现子程序调用的关键所在。
R13 别名SP(stack pointer)栈指针寄存器:用于存放堆栈的栈顶地址的。当我们进行出栈和入栈的时候,都将根据该寄存器的值来决定访问内存的位置(即出入栈的内存位置),同时在出栈和入栈操作完成后,SP寄存器的值也应该相应增加或减少。
R0-R12是普通的数据寄存器,可用于任何地方。R0-R3 常用来传入函数参数,传出函数返回值。R4-R11 常用来存放函数的局部变量。被调用函数返回之前必须恢复这些寄存器的值。R12 内部调用暂时寄存器。
2种状态寄存器:(总个数6)
CPSR(1个)状态寄存器:用于保存程序的当前状态。
SPSR(5个)备份程序状态寄存器: 异常返回后恢复异常发生时的工作状态。
1.跳转指令
B 无条件跳转
BL 带链接的无条件跳转
BX 带状态切换的无条件跳转,根据目标地址最低位切换状态
BLX 带链接和状态切换的无条件跳转
2.数据指令
LDR:从存储器中加载数据到寄存器 ← Load
LDR R8,[R9,#4] R8为待加载数据的寄存器,加载值为R9+0x4所指向的存储单元 R8=*(R9+4)
STR:将寄存器的数据存储到存储器 → Store
STR R8,[R9,#4] 将R8寄存器的数据存储到R9+0x4指向的存储单元 *(R9+4)=R8
LDM:将存储器的数据加载到一个寄存器列表 →
LDM R0,{R1-R3} 将R0指向的存储单元的数据依次加载到R1,R2,R3寄存器
STM:将一个寄存器列表的数据存储到指定的存储器 ←
PUSH:入栈操作(现场保护),将寄存器值推入堆栈
POP:出栈操作(现场恢复),将堆栈值推出到寄存器
SWP:将寄存器与存储器之间的数据进行交换
SWP R1, R1 [R0] 将R1寄存器与R0指向的存储单元的内容进行交换
3.数据传送指令
MOV:将立即数或寄存器的数据传送到目标寄存器 ←
MOV R0, #8 R0=8
4.算术运算指令←
ADD,加法
SUB,减法
5.数据逻辑运算指令
与:AND
或:ORR
异或:EOR
移位: LSL:逻辑左移← LSR:逻辑右移←
LSL R0,R1,#2
LSR R0,R1,#2
6.比较指令
CMP:比较
CMP R0 #0 R0寄存器中的值与0比较
注:
S:Status 表示该指令的执行结果是否影响xPSR的标志位
如:MOV R0,#0
MOVS R0,#0
1.立即寻址
指令举例如下:
SUBS R0,R0,#1 R0 减 1 ,结果放入 R0 ,并且影响标志位
MOV R0,#0xFF000 将立即数 0xFF000 装入 R0 寄存器
2.寄存器寻址
指令举例如下:
MOV R1,R2 将 R2 的值存入 R1
SUB R0,R1,R2 将 R1 的值减去 R2 的值,结果保存到 R0
3.寄存器间接寻址
指令举例如下:
LDR R1,[R2] 将 R2 指向的存储单元的数据读出保存在 R1 中
SWP R1,R1,[R2] 将寄存器 R1 的值和 R2 指定的存储单元的内容交换,将R2的数值作 为一个地址,将此地址处的数值与R1中的内容交换
4.寄存器移位寻址
指令举例如下:
MOV R0,R2,LSL #3 R2 的值左移 3 位,结果放入R0 ,即是R0=R2×8
ANDS R1,R1,R2,LSL R3 R2 的值左移 R3 位,然后和R1相“与”操作,结果放入R1
5.基址寻址
指令举例如下:
LDR R2,[R3,#0x0C] 读取 R3+0x0C 地址上的存储单元的内容,放入 R2
STR R1,[R0,#-4]! 先 R0=R0-4 ,然后把 R1 的值寄存到 R0 指定的存储单元
1.参数的传递只能用R0,R1,R2,R3这四个寄存器(最多只能传四个参数)。
如果超过四个参数,后续的只能是存放在栈空间。
2.函数的返回值只能通过R0返回。如果是64bit的返回,则可以用R1(高),R0(低)。
超过64bit的返回值则不支持。
3.过程调用必须使用现场保护和现场恢复。
现场保护:建议除了传递参数的那个寄存器外,其余的寄存器都进行保护。因为传递参数的寄存器本身就是给另外一个函数使用的,所以不需要保护。
现场恢复:保护了什么就恢复什么。
4.函数返回:将要返回的值传送到R0,然后将LR传送给PC。
Func1 PROC
PUSH {R4-R12,LR} 函数执行前进行现场保护(假设传递了四个参数)
... 函数的代码(内容)
MOV R0,<返回值> 如果有返回值的话就将返回值存至R0中
POP {R4-R12,LR} 函数执行完后进行现场恢复
MOV PC,LR 跳转回主调函数
ENDP
参考资料:
ARM汇编指令_m0_60265426的博客-CSDN博客
ARM汇编基础知识_考古学家lx(李玺)的博客-CSDN博客