裸机开发(2)Cortex-A7简介常用ARM汇编指令

裸机开发(2)Cortex-A7简介常⽤ARM汇编指令
⽬录
1.Cortex-A处理器运⾏模型
ARM的A系列处理器有9种运⾏模型:User、FIQ、IRQ、Supervisor(SVC)、Abort、Undef,Monitor,Hyp和System,其中User是⾮特权模式,其余6中都是特权模式。这9个运⾏模式可以通过软件、中断或者异常来进⾏切换。⼤多数的程序都运⾏在User模式,是不能访问系统所有资源的,要想访问这些受限的资源就必须进⾏模式切换。但⽤户模式不能直接进⾏切换,需要借助异常来完成模式切换,当要切换模式的时候,应⽤程序可以产⽣异常,在异常的处理过程中完成处理器模式切换。当中断或者异常发⽣以后,处理器就会进⼊到相应的异常模式种,每⼀种模式都有⼀组寄存器供异常处理程序使⽤,⽬的是为了保证在进⼊异常模式以后,⽤户模式下的寄存器不会被破坏。STM32只有特权模式和⾮特权模式,但Cortex-A 就有 9 种运⾏模式。
2.Cortex-A寄存器组
2.1.寄存器组简介
ARM架构有16个32位的通⽤寄存器,R0~R14可以⽤作通⽤的数据存储,R15是程序计数器PC,⽤来保存将要执⾏的指令。另外还
有“当前程序状态寄存器CPSR”和“备份程序状态寄存器SPSR”,SPSR是CPSR寄存器的备份。
Cortex-A7 9种模式对应的寄存器如下图,蓝⾊背景的是各个模式所独有的寄存器。在所有的模式中,低寄存器组(R0 ~ R7)共享同⼀组物理寄存器,但⼀些⾼寄存器组在不同的模式有⾃⼰独有的寄存器。
2.2.通⽤寄存器
R0~R15 通⽤寄存器,可以分为以下三类:
①、未备份寄存器,即R0~R7。
②、备份寄存器,即R8~R14。
③、程序计数器PC,即R15。
1. 未备份寄存器
R0 ~ R7。在所有的处理器模式下这8个寄存器都是同⼀个物理寄存器;在不同的模式下这8个寄存器中的数据就会被破坏。
2. 备份寄存器
R8 ~ R12有两种物理寄存器,在快速中断模式下(FIQ)它们对应着Rx_irq(x=8 ~ 12)物理寄存器,其他模式下对应着Rx(8 ~ 12)物理寄存器。因为FIQ模式下的R8 ~ R12是独⽴的,因此中断处理程序可以不⽤执⾏保存和恢复中断现场的指令,从⽽加速中断的执⾏过程。
R13共有8个物理寄存器,⼀个是⽤户模式(User)和系统模式(Sys)共⽤的,剩下7个分别对应7种不同的模式。R13也叫做SP,⽤来做为栈指针应⽤程序会初始化R13,使其指向该模式专⽤的栈地址,这就是常说的初始化SP指针。
R14共有7个物理寄存器,其中⼀个是⽤户模式(User)、系统模式(Sys)和超级监视模式(Hyp)所共⽤的,剩下的6个分别对应6种不同的模式。R14也称为连接寄存器(LR),其在 ARM中主要⽤作如下两种⽤途:
①、每种模式使⽤R14(LR)存放当前⼦程序的返回地址,如果使⽤BL或者BLX来调⽤⼦函数,R14(LR)被设置成该⼦函数的返回地
址,在⼦函数中,将R14(LR)中的值赋给R15(PC)即可完成⼦函数返回。两种⽅法代码如下:
⽅法1.在⼦函数中编写:
MOV PC, LR //寄存器 LR 中的值赋值给 PC,实现跳转
⽅法2.在⼦函数⼊⼝将LR⼊栈:
PUSH {LR}//将LR寄存器压栈
在⼦函数的最后⾯出栈:
POP{PC}  @将上⾯压栈的 LR 寄存器数据出栈给 PC 寄存器
②、当异常发⽣后,该异常模式对应的R14寄存器被设置成该异常模式将要返回的地址,R14也可以当作普通寄存器使⽤。
3. 程序计数器R15
程序计数器R15也叫PC,因为ARM的流⽔线机制,R15保存着当前执⾏的指令地址值加8个字节。ARM处理器3级流⽔线:取指->译码->执⾏,这三级流⽔线循环执⾏,⽐如当前正在执⾏第⼀条指令的同时也对第⼆条指令进⾏译码,第三条指令也同时被取出存放在 R15(PC)中,也就是R15(PC)总是指向当前正在执⾏的指令地址再加上2条指令的地址。对于32位的ARM处理器,每条指令是4个字节,因此R15(PC)值 = 当前执⾏的程序位置+8个字节。
2.3.程序状态寄存器
CPSR是当前程序状态寄存器,被所有模式共⽤,该寄存器包含了条件标志位、中断禁⽌位、当前处理器模式标志等⼀些状态位以及⼀些控制位。所有的处理器模式都共⽤⼀个CPSR会导致冲突,为此除了User和Sys两个模式,其他7个模式都各配备了⼀个专⽤的物理状态寄存器,叫做SPSR(备份程序
状态寄存器)。当特定的异常中断发⽣时,SPSR寄存器⽤来保存当前程序状态寄存器(CPSR)的值,当异常退出以后可以⽤SPSR中保存的值来恢复CPSR。因为User和Sys不是异常模式,所以并没有配备SPSR,因此不能在User和Sys模式下访问SPSR,会导致不可预知的结果。SPSR和CPSR的寄存器结构相同。
CPSR寄存器:
1. N(bit31):当两个补码表⽰有符号整数运算时,N=1表⽰运算结果为负,N=0表⽰结果为正。
2. Z(bit30):Z=1表⽰运算结果为零,Z=0 表⽰不为零,对于CMP指令Z=1表⽰进⾏⽐较的两数相等。
3. C(bit29):加法指令中当结果产⽣了进位,C=1;减法指令中当运算发⽣借位,则C=0。这不是戏
4. V(bit28):对于加/减法运算指令,V=1表⽰符号位溢出。
5. Q(bit27):仅ARM v5TE_J架构⽀持,表⽰饱和状态,Q=1表⽰累积饱和,Q=0表⽰累积不饱和。
6. IT[1:0] (bit26:25):和IT[7:2] (bit15:bit10)⼀起组成IT[7:0],作为IF-THEN指令执⾏状态。
hrb400
7. J(bit24):仅ARM_v5TE-J架构⽀持,J=1表⽰处于Jazelle 状态,此位通常和T(bit5)位⼀起表⽰当前所使⽤的指令集:上位机软件
J T描述
00ARM
01Thumb
J T描述
11ThumbEE
10Jazelle
8. GE[3:0] (bit19:16):SIMD指令有效,⼤于或等于。
9. IT[7:2] (bit15:10):参考 IT[1:0]。
10. E(bit9):⼤⼩端控制位,E=1表⽰⼤端模式,E=0表⽰⼩端模式。
11. A(bit8):禁⽌异步中断位,A=1表⽰禁⽌异步中断。
12. I(bit7):I=1禁⽌IRQ,I=0使能 IRQ。
13. F(bit6):F=1禁⽌FIQ,F=0使能FIQ。
14. T(bit5):参考J(bit24)。
15. M[4:0]:处理器模式控制位,含义如表所⽰:
M[4:0]处理器模式
10000User模式
10001FIQ模式
10010IRQ模式
10011Supervisor(SVC)模式
10110Monitor(MON)模式
10111Abort(ABT)模式
气泡式水位计11010Hyp(HYP)模式
11011Undef(UND)模式
11111System(SYS)模式
甬台温铁路3.GUN汇编语法
在Cortex-A芯⽚上电后,需要⽤户写程序,使⽤汇编语⾔初始化SP指针,使其指向栈顶,并且需要初始化DDR等操作(因为芯⽚可能没有向⽤户开放的ram),最后再进⼊C语⾔的main。由于我们编写的是ARM汇编,使⽤GCC交叉编译器编译,所以汇编代码要符合GNU语法,GNU语法的格式是:label:instruction @ comment。
可以使⽤“.section”伪操作来定义⼀个段,可以⾃定义段名称,也可以使⽤汇编系统预定义的段名:
段名含义
.text表⽰代码段
.data初始化的数据段
.
bss未初始化的数据段
.rodata只读数据段
汇编程序的默认⼊⼝标号是_start,也可以在链接脚本中使⽤ENTRY来指明其它的⼊⼝点。下⾯代码中.global 是伪操作,表⽰_start 是⼀个全局标号,类似 C 语⾔⾥⾯的全局变量。
.global _start
_start:
ldr r0,=0x12 @r0=0x12
还有其他常⽤伪操作:
名称举例
.byte定义单字节数据,⽐如.byte 0x12
.short定义双字节数据,⽐如.short 0x1234
.long定义⼀个 4 字节数据,⽐如.long 0x12345678
.equ赋值语句,⽐如.equ num, 0x12,表⽰num=0x12
海尔w36.align数据字节对齐,⽐如:.align 4 表⽰ 4 字节对齐
.end表⽰源⽂件结束
.global定义⼀个全局符号,⽐如:.global _start
4.ARM常⽤汇编指令
处理器内部数据传输命令:
1. MOV指令,⽤于将数据从⼀个寄存器拷贝到另外⼀个寄存器,或者将⼀个⽴即数传递到寄存器。
MOV R0,R1    @将寄存器R1中的数据传递给R0,即R0=R1
MOV R0, #0X12 @将⽴即数0X12传递给R0寄存器,即R0=0X12
2. MRS指令,⽤于将特殊寄存器(如CPSR和SPSR)中的数据传递给通⽤寄存器。
MRS R0, CPSR  @将特殊寄存器CPSR⾥⾯的数据传递给R0,即R0=CPSR
3. MSR指令,和MRS相反,⽤来将普通寄存器的数据传递给特殊寄存器。
MSR CPSR, R0  @将R0中的数据复制到CPSR中,即CPSR=R0
存储器访问指令:
4. LDR指令,LDR Rd, [Rn , #offset] ,从存储器Rn+offset的位置读取数据存放到Rd中。
字节操作是LDRB,半字操作是LDRH。
LDR R0,=0X0209C004 @将寄存器地址0X0209C004加载到 R0 中,即 R0=0X0209C004
LDR R1,[R0]        @读取地址0X0209C004中的数据到 R1 寄存器中
5. STR指令,STR Rd, [Rn, #offset] ,将Rd中的数据写⼊到存储器中的Rn+offset位置。字节操作是STRB,半字操作是STRH。
LDR R0,=0X0209C004 @将寄存器地址0X0209C004加载到 R0 中,即 R0=0X0209C004
LDR R1,=0X20000002 @R1 保存要写⼊到寄存器的值,即 R1=0X20000002
STR R1,[R0]        @将 R1 中的值写⼊到 R0 中所保存的地址中
压栈和出栈指令:
通常会在A函数中调⽤B函数,B函数执⾏完以后再回到A函数继续执⾏。必须在跳到B函数前保存当前处理器状态(R0 ~ R15寄存器值,即保护现场),B函数执⾏完后再恢复R0 ~ R15即可(即恢复现场)。保护现场需要进⾏压栈操作(PUSH指令),恢复现场要进⾏出栈操作(POP指令)。PUSH和POP是多存储和多加载指令,利⽤当前的栈指针SP来⽣成地址,能⼀次操作多个寄存器。
6. PUSH < reg list >,将寄存器列表存⼊栈中,也可写作“STMFD SP!”。
7. POP < reg list >,从栈中恢复寄存器列表,也可写作“LDMFD SP!”。
跳转指令:
8. B指令,能将PC寄存器的值设置为跳转⽬标地址, 执⾏后ARM处理器就会⽴即跳转到指定的⽬标地址,不再返回原地址。

本文发布于:2024-09-22 04:20:02,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/190749.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:寄存器   模式   指令   程序   数据   函数
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议