1.Supervisor模式与SVC模式
所以,Supervisor模式和SVC模式在ARM处理器中是不同的概念,但它们之间有密切的关联。SVC模式使用Supervisor模式的功能来提供系统服务。
2.指令+s的作用,影响N,Z,C,V位
ARM指令中的“S”后缀用于指示该指令执行后是否更新程序状态寄存器(CPSR)的条件标志位。这些标志位可以用于后续的条件判断或分支操作,从而影响指令的执行顺序。
以下是具体功能和详细解释:
条件标志位更新:当ARM指令后带有“S”后缀时,该指令执行后,程序状态寄存器的条件标志位(如N、Z、C、V等,分别代表负数、零、进位和溢出)将被刷新或更新。这些标志位经常用于对条件进行测试,例如是否溢出、是否进位等。
影响指令执行顺序:根据这些条件标志位的变化,程序可以执行不同的分支或循环,从而影响指令的执行顺序。例如,可以使用这些标志位来判断一个加法操作是否导致溢出,然后根据结果选择不同的后续指令。
指令格式:在ARM指令中,后缀“S”是可选的。当不使用“S”后缀时,指令执行后程序状态寄存器的条件标志位将不会发生变化。指令的一般格式可以表示为,其中是操作码,是可选的条件码,是目标寄存器,是存放第一操作数的寄存器,是第二操作数。
具体示例:以加法指令为例,ADD R3, R5, R8(没有使用“S”后缀)执行后,条件标志位将不会发生变化;而ADDS R3, R5, R8(使用了“S”后缀)执行后,条件标志位将根据结果刷新。
3.CPSR(程序状态寄存器)/SPSR(程序状态保存寄存器)
在ARM架构中,CPSR(Current Program Status Register,当前程序状态寄存器)和SPSR(Saved Program Status Register,程序状态保存寄存器)是两个重要的状态寄存器,它们在处理器中扮演着关键的角色。以下是关于这两个寄存器的详细解释:
N和C标志位被“置位”,指的是这些标志位被设置为特定的值以表示某种状态或条件。
功能与作用:
内容详解:
访问方式:
功能与作用:
内容详解:
注意:
总结:
4.跳转指令和加载指令
4.1跳转指令(b/bl/bx)
b:无条件跳转指令;
bl:用于函数调用,并在lr寄存器中保存返回地址。
bl和b之间的区别就在于bl会在lr寄存器中保存回来的地址。
bx:回到调用处,即:返回主调函数。
bxgt:满足gt条件时,回到调用处。(gt:>, ge:>=)
bx 基于寄存器的内容进行跳转,并支持 ARM/Thumb 切换。
4.2 加载指令(LDR)
LDR{条件} 目的寄存器, <存储器地址>LDR R0, [R1]:将存储器地址为R1的字数据读入寄存器R0。LDR R0, [R1, #8]:将存储器地址为R1+8的字数据读入寄存器R0。5.ARM中常见的数据处理指令
ADD:
ADD R1, R2, R3 将 R2 和 R3 的值相加,并将结果存储在 R1 中。SUB:
SUB R1, R2, R3 从 R2 中减去 R3 的值,并将结果存储在 R1 中。ARM指令集中的数据处理指令是用于在寄存器中执行数学运算、逻辑运算以及数据传送的指令。这些指令在ARM架构中扮演着核心角色,允许CPU高效地执行各种计算任务。以下是一些ARM中常见的数据处理指令,按照其功能分类进行归纳:
这些指令共同构成了ARM指令集中的数据处理部分,允许开发者在ARM架构的CPU上执行各种复杂的计算任务。需要注意的是,ARM指令集在不同的版本(如ARMv7、ARMv8等)中可能会有所不同,上述指令是ARM指令集中常见的和通用的部分。
6.栈的实现类型:
2440实现保护和恢复现场使用的栈是数组栈,即用一段连续的内存空间为栈提供空间。从数组栈的具体实现来看入栈的方式有四种做法:
arm体系采用的方案是满减,但是在进行操作之前,我们必须告诉2440栈底的位置,这里我们把栈底设置为0x40001000,从地址0x40000000开始的0x1000这段内存空间对应的是2440内部的一段ram,总共4k。实际能够使用的内存空间为[0x40000000~0x40000FFF],设置栈底指针寄存器: ldr sp =0x40001000
6.1入栈保护指令stmfd(STMDB)
STMFD
其中Rn表示栈底指针寄存器,< registers >表示需要入栈保护的寄存器,!表示入栈之后sp自动自减。如:
stmfd sp!, {r0, r1, r2, r3-r12, lr} ;保护现场
6.2出栈恢复指令ldmfd(LDM/LDMIA/)
LDMFD
中Rn表示栈底指针寄存器,< registers >表示需要入栈保护的寄存器,!表示出栈之后sp自动自增。如:
ldmfd sp!, {r0, r1, r2, r3-r12, lr} ;恢复现场

7.汇编与C语言代码互相调用规则
7.1在汇编中调用c语言编写的函数
设有c语言定义的函数void func_c(void);在汇编代码中调用该函数,只需用import(导入)声明函数名即可,之后就可以使用bl指令调用该函数,注意,既然是调函数,就一定要保护现场。

7.2 向c函数传参
向c函数传参的方法很简单,如果参数个数小于等于4个,就直接用r0~r3传参,c函数返回值通过r0寄存器返回:
设有c函数:
int add_c(int a, int b, int c, int d)
{
return a + b + c + d;
}

如果参数个数大于4个,从第五个参数开始就需要通过栈来传参(前4个参数传参,通过r0-r3传参,返回值用r0传参)

在c语言中调用汇编编写的函数类似,不过在汇编中用export声明函数,同时需要在c语言中用extern声明函数,按照标准,调用者负责保护现场和恢复现场

传参方法于此类似
8.切换ARM内核的工作模式
mrs:读取CPSR的状态;
msr:写入CPSR寄存器。
切换工作方式的思路很简单,由于内核的工作模式是由cpsr寄存器的低5位来设置的,那么就可以先把cpsr读出来,更改低5位之后再设置进去。这里读取cpsr使用mrs指令,写cpsr寄存器用msr指令,需要注意的是在keil环境下写cpsr需要写成: msr cpsr_c r0;将r0的值写入到cpsr寄存器