VPN - Fast VPN Proxy 03_ARM体系结构_Cortex-A系列 官方正式版


- 软件评分: ★★★★
- 最后更新: 2025-06-12 22:08:42
- 好评人数: 5109
- 应用分类: 软件下载
- 使用语言: 中文
- 网络支持: 需要联网
内容大纲VPN - Fast VPN Proxy
1、ARM架构和处理器
2、工具、操作系统和开发板
3、ARM寄存器、数据类型、模式和指令集
4、ARM汇编语言
5、SIMD和NEON
6、ARM缓存(Caches)架构
7、内存管理单元
8、中断处理(Interrupt Handling)
9、异常处理(Exception Handling)
10、启动代码
11、多处理器结构
官方资料
架构资料
2. ARM架构和处理器3. 相关术语介绍架构版本演变ARMv4 -> ARMv5 -> ARMv6 -> ARMv7
相关术语
流水线:三级流水:取值(Fetch) - 译码(Decode) - 执行(Exe)
DSP - 数字信号处理
Jazelle:ARM针对java的
ThumbEE:Thumb指令是辅助ARM指令的另外一个指令
Thumb-2:
TrustZone:
VFP(Vector Floating-Point):浮点运算
Advaced SIMD(NECO):
Large Physical Address Extension(LPAE):大物理地址扩展
Virtualization:虚拟化
Big LITTLE:大小核 - 省电
A系列关键技术点
32位RISC处理器,有16个32位的 可见寄存器
哈佛结构(指令和数据分开)
Thumb-2 指令支持
VFP和NEON可选
向后兼容
4GB虚拟地址空间和最小4GB物理地址(4GB寻址)
内存虚拟页大小 4KB、64KB、1MB 和 16MB
大小端数据访问支持
4. 工具、操作系统和开发板4.1. 有用的工具QEMU:Linux虚拟机
QEMU是一套由Fabrice Bellard所编写的模拟处理器的自戌软件。它与Bochs,PearPC近似,但其具有某些后两者所不具备的特性,如高速度及跨平台的特性.。经由kqeu这个开源的加速器,QEMU能模拟至接近真实电脑的速度。
BusyBox:做Linux的根文件系统
BusyBox是一个集成了一百多个最常用Iiux命令和工具的软件。BusyBox包含了一些简单的工具,例如ls、cat和echo等等,还包含了一些更大、更复杂的工具,例如grep、fnd、mount以及telnet。有些人将BusyBox称为Linux工具里的瑞士军刀。简单的说BusyBoxs就好象是个大工具箱,它集成压缩了Liux的许多工具和命令,也包含了Android系统的自带的shell。
Scratchbox:交叉编译工具
Scratchbox是一个帮助嵌入式Linux跨平台编辉工具的集合,其目的主要是使得嵌入式Linux应用程序开发更加容易,他也提供了完整的集成工具链以用来跨平台编译集成出一个Liu以发布版。这个计划最初是由Movial开发以及由Nokia赞助,是符合GNU General Public License(GPL)发布的·
uboot:做Linux的bootloader
U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。大名鼎鼎的开源Bootloader
UEFI and Tianocore
UEF统一可扩展部件接口,它的诞生,以及我们要绕过它。
4.2. ARM软件工具链(ToolChains)两个工具链
GNU 包含gcc
ARM 包含armcc
用工具链生成镜像的过程
预处理 编译 汇编 链接
4.2.1. GNU ToolchainGNU工具链既可以用来开发内核也可以用来开发应用程序,包含以下组件
GNU makeVPN - Fast VPN Proxy
GNU Compiler Collection (GCC)
GNU binutils linker,assembler,and other object/library manipylation tools
GNU debugger (GDB)
GNU build system (autotools)
GNU C library (glibc or eglibc)
其他工具
addr2line:把程序地址转换位文件名和行号
ar:简历、修改、提取归档文件
as:主要用来编译GNU C编译器gcc输出的汇编文件
ld:GNU链接器
nm:列出目标文件中的符号
objcopy:文件格式转换。
objdump:显示一个或者更多目标文件的信息,主要用来反编译
ranllib:产生归档文件索引,并将其保存到这个归档文件中
readelf:显示elf格式可执行文件的信息
size:列出目标文件每一段的大小及总体的大小
strings:打印某个文件的可打印字符串
strip:丢弃目标文件中的全部或者特定符号,减小文件体积
ubuntu中安装标准工具链
sudo apt install gcc g++ gcc-doc
ubuntu中安装交叉工具链
sudo apt-get install gcc-arm-linux-gnueabi eabi embedded(嵌入式) application(应用) binary(二进制) interface(接口)
gnu官方网址下载:https::/www.linaro.org/downloads
开发板工具包里有:arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz解压缩之后加入到系统路径底下即可用4.2.2. ARM 编译工具
ARM Compiler需要付费
5. ARM寄存器模式5.1. ARM指令集和Thumb指令集ARM指令 - 32位指令集
Thumb指令 - 16位指令集(代码密度更高,但性能低)
Thumb-2 16位和32位混合指令集( Cortex-A支持)
5.2. CPU组成ALU:逻辑运算单元 (运算器)
控制器
寄存器:CPU内部存储器
内部总线
5.3. 处理器模式ARM架构有9种处理器模式,8种特权模式,一种非特权模式,即用户模式
模式名称编码功能User(USER)10000大部分程序运行时候的非特权模式FIQ10001进入FIQ中断异常IRQ10010进入IRQ中断异常Supervision(SVC)10011管理调用指令被执行或者reset的时候Monitor(MON)10110安全扩展模式,只用于安全Abort(ABT)10111存储访问异常Hyp(HYP)11010虚拟化扩展Undef(UND)10011未定义的指令执行的时候System(SYS)11111特权模式,与用户模式共享寄存器5.4. 寄存器通用寄存器(存放通用数据 32bit):R0、R1、R2、R3、R4、R5、R6、R7、R8、R9、R10、R11、R12、
栈指针:R13 (SP)
链接寄存器:R14 (LR) 存储子程序返回地址
程序计数器:R15 (PC)
应用程序状态寄存器/当前程序状态寄存器:APSR/CPSR
已存储程序状态寄存器:SPSR
1、R0 - R12 通用寄存器,放通用数据,32 bit2、各个模式的R0-R12与USER模式是共享的(除了FIQ,R8-R12),PC,CPSR共享的3、USR模式没有SPSR
例子1、程序返回:其实就是 MOV PC,LR (LR -> PC)2、跳转:BL
CPSR 指令格式
N:ALU负数
Z:ALU零位
C:ALU 进位操作
V:ALU操作溢出
Q:累计饱和instructions
J:是否Jazelle状态
GE[3:0]:SIMD指令使用
IT[7:0]:Thumb-2指令的 if...then条件执行
E:操作存储的字节顺序
A:是否disable异步abortVPN - Fast VPN Proxy
I:disables IRQ
5.5. 指令流水线Pipeline三级指令流水线取指-译码-执行
扩展到五级流水
指令预读取(决定从哪儿取指令) PreFetch
指令读取(从内存系统中读取指令)
指令译码(解读指令并且生成控制信号)
寄存器读取(提供寄存器的值给操作单元)
分配(分配指令给执行单元)
执行(实际的ALU单元处理)
内存访问(数据的存取)
多处理流水线双ALU流水线和超标量流水线(Cortex-A8/A9)
5.6. 分支预测现在的动态预测 BTAC
返回栈(Stack Return) 预测子程序返回地址存在哪里
6. ARM汇编语言程序 = 数据结构 + 算法
6.1. 导言向寄存器里添加一个值添加100
X86:add eax,#10068K:ADD #100,D0ARM:ADD r0,r0,#100
从一个寄存器指针加载到寄存器
X86:mov eax,DWORD PTR [ebx]68K:MOVE.L (A0),D0ARM:ldr r0,[r1]
一个完整的ARM汇编指令格式 Operation(cond)(s) Rd,Rn,Operand2
Operation 操作指令 例如ADD
cond 条件
s 状态
Rd 目标寄存器
Rn 源寄存器
Operand2 后续附加操作
例如
AREA testhello,CODE,READONLY ENTRY CODE32START ADD R1,R2,#4 MOV R5,R1 END
AREA testhello,CODE,READONLY AREA表示一个区域,后面跟的区域名,CODE表示该段放在代码区,READONLY表示只读
ENTRY 表示入口
CODE32表示用32位指令
START 表示程序起使处
ADD R1,R2,#4 将R2寄存器里的值加上4给R1
MOV R5,R1 将R1里的值给R5
# 后面表示立即数,立即数条件:
上面两个指令,缺少条件指令和状态指令
条件指令
MOVEQ R5,R1 将R1里的值给R5这里的EQ是条件指令,表示上一条比较语句的成员如果相等的话则移动数据还有很多条件语句,例如NE不相等CS等,可以查手册
状态指令N NegetiveZ ZeroC Carry 进位V overflow 溢出
关于立即数:https://blog.csdn.net/tabactivity/article/details/90266999
6.2. 寻址方式立即数寻址
ADD R0,R0,#0X3F
寄存器寻址
ADD R0,R1,R2
寄存器间接寻址
LDR R0,[R1] 把R1存的值当作内存地址,取该内存地址的值放到R0
STR R0,[R1] 把R0放到内存地址里
寄存器移位寻址
ADD R3,R2,R1,LSL #2 把R1里的数左移两位,加上R2的值给R3
基地址寻址
LDR R0,[R1,#4] 将R1里的值+4所得到的值作为内存地址,取内存地址里的值给R0
LDR R0,[R1],#4 将R1里的值作为内存地址,取出的值+4给R0
LDR R0,[R1,R2] 将R1的值加上R2的值作为地址取出的值给R0
多寄存器寻址
LDMIA R0,{R1,R2,R3,R4} 所有寄存器里的值全部加起来赋给R0
相对寻址
BL NEXT 跳转 到NEXT标号
MOV PC,LR 把LR寄存器的值给PC 也有跳转的作用
熟悉以下几个概念
满堆栈
空堆栈
递增堆栈
递减堆栈
6.3. 算数操作数学操作
OpcodeOperandsDescriptionFunctionADCRd,Rn,Op2带进位的加Rd = Rn+Op2+CADDRd,Rn,Op2加Rd = Rn+Op2MOVRd,Op2数据传送Rd = Op2MVNRd,Op2数据取反传送Rd = ~Op2RSBRd,Rn,Op2翻转减Rd = Op2-RnRSCRd,Rn,Op2带进位的翻转减Rd = Op2-Rn-!CSBCRd,Rn,Op2带进位的减Rd = Rn-Op2-!CSUBRd,Rn,Op2减Rd = Rn-Op2MULRd,Rm,Rs32位乘法Rd = Rm*RsMLARd,Rm,Rs,Rn32位累加乘法Rd = Rm*Rs+RnUMULLRdLo,RdHi,Rm,Rs64位无符号乘法(RdLo,RdHi)=Rm*RsUMLALRdLo,RdHi,Rm,Rs64位无符号累加乘法(RdLo,RdHi)=Rm*Rs+(RdLo,RdHi)SMULLRdLo,RdHi,Rm,Rs64位有符号乘法SMLALRdLo,RdHi,Rm,Rs64位有符号累加乘法逻辑操作
OpcodeOperandsDescriptionFunctionANDRd,Rn,Op2逻辑与Rd=Rn&Op2BICRd,Rn,Op2位清零(逻辑非)Rd=Rn&~Op2EORRd,Rn,Op2逻辑异或Rd=Rn^Op2ORRRd,Rn,Op2逻辑或`Rd=Rn比较操作
OpcodeOperandsDescriptionFunctionCMPRn,Op2比较Rn-Op2CMNRn,Op2负数比较Rn-Op2TEQRn,Op2测试相等Rn&Op2TSTRn,Op2测试Rn^Op26.4. 内存操作单寄存器读写指令
OpcodeOperandsDescriptionFunctionLDRRn,Addr按照字长(word)读取(从内存)LDR R0,[R1]LDR R0,[R1,#4]STR按照字长(word)写入(到内存)LDRB按照字节STRB字节LDRHharfword 半字STRH半字LDRBT用户模式 字节STRBT用户模式 字节LDRT用户模式 字STRT用户模式 字LDRSB有符号字节LDRSH有符号半字多寄存器内存访问指令
OpcodeOperandsDescriptionFunctionLDM从R0取出地址,然后基于此,将内存的值拷贝到后面的寄存器组,依次递增(看规则)LDMIA R0,STMSTMIA R0,地址模式数据块模式:IA (传输后地址加4)、IB (传送前地址加4)、DA (传送后地址减4)、DB (传送前地址减4)堆栈模式:EA (空递减堆栈)、FD (满递减堆栈)、ED (空递增堆栈)、FA (满递增堆栈)
基地址不能用R15
数据交换指令
OpcodeOperandsDescriptionFunctionSWPRd,Rn1,[Rn2]内存和寄存器交换[Rn2] -> Rd,Rn1 -> [Rn2]如果Rd和Rn1相同就是直接交换SWPB字节交换6.5. 跳转操作跳转、状态操作
OpcodeOperandsDescriptionFunctionB跳转指令pc BL带返回的连接跳转pc BX跳转并切换状态ThumbBLX待返回的跳转并切换状态Thumb状态寄存器操作:把32位指令分为4个域:[7:0]控制位域c,[15:8]扩展位域x,[23:16]状态位域s,[31:24]条件位域f
OpcodeOperandsDescriptionFunctionMRS把程序状态寄存器的值传送到通用寄存器MSRCPSR,R0SPSR,R0CPSR_c,R0通用寄存器到程序状态寄存器异常产生的指令
OpcodeOperandsDescriptionFunctionSWISWI 0x02软中断指令BKPTBKPT断点中断指令6.6. 伪指令6.6.1. 伪指令作用及类别我们的指令已经可以做各类操作了,但我们操作起来太麻烦了。比如我现在要设置一个值给寄存器R0,但下次我修改了寄存器R0之后又需要读出来刚才的值,那我们就要先临时保存值到SPSR or CPSR,然后不断切换。再比如,我们要做一个循环,就要用label结合BL不断进行,但如果我们要循环很多次。我们就定义了一些类似于带参数的宏的操作一样,来定义我们的伪指令,方便我们更好的实现汇编程序逻辑。伪指令只是在汇编器之前作用,汇编之后会翻译为标准的汇编指令集。我们又分为ARM汇编伪指令和GNU汇编伪指令。
6.6.2. 基本常用伪指令OpcodeOperandsDescriptionFunctionAREAAREA test,CODE,READONLY声明区域段,数据区,代码区等等CODE16、CODE32CODE32声明以下是32位还是16位指令,注意不是切换arm和thumb模式ENTRYENTRY伪指令用于指定汇编程序的入口点。在一个完整的汇编程序中至少要有一个ENTRY(也可以有多个,当有多个ENTRY时,程序的真正入口点由链接器指定),但在一个源文件里最多只能有一个ENTRY(可以没有)。ENDENDEND伪指令用于通知编译器已经到了源程序的结尾EQUUARTLCON0 EQU 0x3FFD000EQU伪指令用于为程序中的常量、标号等定义一个等效的字符名称,类似于C语言中的#define。其中EQU可用'*'代替EXPORT.globalEXPORT伪指令用于在程序中声明一个全局的标号,该标号可在其他的文件中引用。EXPORT可用GLOBAL代替。标号在程序中区分大小写,[WEAK]选项声明其他的同名标号优先于该标号被引用IMPORT相当于静态引用IMPORT伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前的源文件中引用,而且物理当前源文件是否引用该标号,该标号就不会被加入到当前源文件的符号表中EXTERN相当于动态引用EXTERN伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,如果当前源文件实际并未引用该标号,该标号就不会被加入到当前源文件的符号表中GET相当于引用文件GET伪指令用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理,可以使INCLUDE代替GETRNSRegister RN R0RN伪指令用于给一个寄存器定义一个别名6.6.3. 在汇编语言程序中常用的符号6.6.3.1. 符号命名原则符号区分大小写,同名的大、小写符号会被编译器认为是两个不同的符号。
符号在其作用范围内必须唯一·
自定义的符号名不能与系统的保留字相同。
符号名不应与指令或伪指令同名
关于ADS里面可恶的Tab和顶行'ADS Style'
6.6.3.2. 符号、变量ARM (Thumb)汇编程序所支持的变量有数字变量、逻辑变量和字符串变量
OpcodeOperandsDescriptionFunctionGBLA/GBLL/GBLSGBLA Test3定义全局数字/逻辑/字符串变量LBLA/LBLL/LBLSLBAL Test3声明局部变量SETA/SETL/SETSTest3 SETA Oxaa设定变量值不能有TabRLISTRegList RLIST (RO-R5,R8,R10}将寄存器列表名称定义为RegList,可在ARM指令LDM/STM中通过该名称访问寄存器列表。不能有Tab定义变量存储在寄存器中还是内存中?内存中。
6.6.3.3. 常量数字常里一般为32位的整数,当作为无符号数时,其取值范围为0232-1,当作为有符号数时,其取值范围为-231231-1。
逻辑常里只有两种取值情况:真或假。
字符串常里为一个固定的字符串,一般用于程序运行时的信息提示
6.6.3.4. 变量代换程序中的变里可通过代换操作取得一个常里。代换操作符为“$”
SampleLCLS S1LCLS S2S1 SETS“Test!wS2 SETS“This is a SS1”;字符串变里S2的值为“This is a Test!”6.6.3.5. 表达式和运算符
“+”、“-”、“×”、“/”及“MOD”算术运算符
“ROL”、“ROR”、“SHL”及“SHR”移位运算符
“AND”、“OR”、“NOT”及“EOR”按位逻辑运算符逻辑表达式及运算符
“=”、“>”、“=”、“C=”、“/e”、“”运算符
“LAND”、“LOR”、“LNOT”及“LEOR”运算符
6.6.4. 寄存器操作OpcodeOperandsDescriptionFunctionLDR R0,=0x12某时候可以提到MOV,MVN大范围寻址到寄存器-绝对寻址ADR R0,=as小范围寻址到寄存器ADRL中范围寻址到寄存器6.6.5. 数据定义伪汇编OpcodeOperandsDescriptionFunctionDCBname DCB value用于分配一片连续的字节存储单元并用指定的数据初始化DCB也可用=代替DCW用于分配一片连续的半字存储单元并用指定的数据初始化DCD用于分配一片连续的字存储单元并用指定的数据初始化DCFD浮点双精度DCFS浮点单精度DCQ8字节为单位SPACEtest SPACE 100用于分配一片连续的存储单元,并初始化为0,单位为字节MAPMAP0x100.;定义结构化内存表首地址的值为0x100。A FIELD16;定义A的长度为16字节,位置为0x100B FIELD 32;定义B的长度为32字节,位置为0x110S FIELD 256;定义S的长度为256字,位置为0x130用于定义一个结构化的内存表首地址MAP也可用'^'代替FIELD用于定义一个结构化的内存表的数据域FILED也可用#代替6.6.6. 控制伪指令OpcodeOperandsDescriptionFunctionIF ELSE ENDIF条件语句WHILE WEND循环语句MACRO MEND宏定义MEXIT跳出宏6.7. 混合编程6.7.1. 为什么要混合编程1、可扩展性、可维护性2、兼容性
6.7.2. 汇编和C、C++混合编程的方式汇编语言与C/C++的混合编程通常有以下几种方式:
在C/C++代码中入汇编指令。
在汇编程序和C/C++的程序之间进行变里的互访
汇编程序、C/C++程序间的相互调用。
6.7.3. C语言嵌入汇编格式:__asm [volatile]{instruction} [;instruction]
限制条件
不能直接向PC寄存器赋值,程序跳转要使用B或者BL指令
在使用物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突
R12和R13可能被编译器用来存放中间编译结果,计算表达式值的时候京可能的把R0-R3、R12及R14用于子程序调用,因此避免直接使用这些物理寄存器
6.7.4. C语言调用汇编C语言调用汇编步骤1、汇编export2、C语言定义extern function3、C语言使用
C语言和汇编语言之间的参数传递是通过对应的用R0-R3来进行传递,即R0传递第一个参数,R1传递第二个参数,多于4个的时候借助栈完成,函数的返回值通过R0来传递、这个规定叫做ATPCS。6.7.5. 汇编调用C语言
汇编使用C语言步骤1、C语言实现函数2、汇编import函数名3、BL函数名
int cFun(int a,int b,int c){ return a+b+c; }
start MOV R0,#1 MOV R1,#2 MOV R2,#3 BL cFun MOV R4,R0
最终结果通过R0返回,赋给R4
①谨慎填写个人资料,避免泄露身份证号、住址等敏感信息;
②警惕陌生人的金钱交易请求,切勿轻信高收益理财、转账返利等话术;
③遇到骚扰/不良信息请立即屏蔽举报;
④未成年人使用时建议开启家长监护模式;
⑤合理控制使用时长,注意保护视力。平台将持续加强APP安全审核,与您共建清朗网络空间。
选择评分 *
评论内容 *
昵称 *
Email *