嵌入式软件常用面试题汇总之 ARM 平台开发相关(2)
ARM架构之常考基础知识汇总
这部分还是有可能会问到的,但基本上只要有了解到就是加分项了,毕竟其实工作大部分时间不需要到了解很深。
1.ARM中 CPSR 和 SPSR 的作用是什么?
CPSR (Current Processor Status Register) 是当前程序状态寄存器,用于存储当前处理器的状态信息.
SPSR (Saved Processor Status Register)是保存程序状态寄存器,专用于异常处理。当发生异常(比如中断、系统调用等)时,处理器会将当前的 CPSR 内容保存到 SPSR 中,当异常处理完成时会将 SPSR 的内容恢复到 CPSR 中,以便程序继续执行异常发生前的状态,这样在异常处理完成后可以恢复原有的状态。
2.ARM中各种工作模式对SPSR寄存器是共用的么?CPSR呢?
SPSR 是不共享的,每种异常模式(比如 FIQ、IRQ、Supervisor、Abort、Undefined 等)都有自己独立的 SPSR 寄存器。这样做的目的是为了在不同的异常模式下保存各自的处理器状态,而不互相干扰。每个异常模式的 SPSR 保存了进入该模式时的 CPSR 内容,因此处理器可以在不同的异常模式下自由切换并保存状态。
CPSR 是共享的,所有模式下都使用同一个 CPSR 寄存器。CPSR 记录了当前处理器的整体状态,包括条件标志位、控制位(如中断屏蔽标志)和处理器模式位等。由于 CPSR 是唯一的,因此在不同模式切换时,处理器必须保存当前的 CPSR 内容到该模式的 SPSR 中,以确保能够在异常处理完成后恢复之前的状态。
3.ARM中对栈的使用方式有哪几种?常用的是哪一种?
在 ARM 处理器中,栈的使用方式主要有以下几种,这些方式决定了数据在栈中的增长方向和栈指针(SP)的更新方式。ARM 的栈使用可以分为四种主要模式:
1. 全递增栈(Full Ascending Stack)
特点:栈从低地址向高地址增长。
操作方式:栈指针(SP)指向栈的最后一个有效元素,即栈的顶部元素。
Push 操作:先存入数据,再增加栈指针。
Pop 操作:先减少栈指针,再读取数据。
2. 全递减栈(Full Descending Stack)
特点:栈从高地址向低地址增长。
操作方式:栈指针(SP)指向栈的最后一个有效元素,即栈的顶部元素。
Push 操作:先存入数据,再减少栈指针。
Pop 操作:先增加栈指针,再读取数据。
3. 空递增栈(Empty Ascending Stack)
特点:栈从低地址向高地址增长。
操作方式:栈指针(SP)指向栈的第一个空位置,即栈的顶部的下一个地址。
Push 操作:先增加栈指针,再存入数据。
Pop 操作:先读取数据,再减少栈指针。
4. 空递减栈(Empty Descending Stack)
特点:栈从高地址向低地址增长。
操作方式:栈指针(SP)指向栈的第一个空位置,即栈的顶部的下一个地址。
Push 操作:先减少栈指针,再存入数据。
Pop 操作:先读取数据,再增加栈指针。
常用的栈模式是全递减栈,因为它符合通常的栈增长方向(高地址向低地址)
4.ARM处理器有几种寻址方式?
1. 立即寻址(Immediate Addressing)
在立即寻址中,操作数直接包含在指令中。通常用于加载常数或小的数值到寄存器中。这种方式执行速度快,但操作数的范围受限于指令格式的长度。
示例:
MOV R0, #5 ; 将常数 5 加载到 R0 中
2. 寄存器寻址(Register Addressing)
寄存器寻址方式直接使用寄存器的值作为操作数。这种寻址方式简单高效,且执行速度很快,因为不需要访问内存。
示例:
MOV R1, R2 ; 将 R2 的值复制到 R1
3. 寄存器间接寻址(Register Indirect Addressing)
在寄存器间接寻址中,寄存器的值用作内存地址,而操作数存储在该内存地址中。这种方式常用于访问数组或指针指向的内存地址。
示例:
LDR R1, [R2] ; 将内存地址 R2 指向的值加载到 R1 中
4. 基址变址寻址(Base Plus Offset Addressing)
基址变址寻址是一种常见的内存寻址方式,其中一个寄存器提供基址,偏移量可以是立即数或寄存器的值。偏移量可以加到基址上,也可以从基址中减去。这种方式常用于结构体成员访问或数组索引访问。
示例:
LDR R0, [R1, #4] ; 将 R1+4 地址的值加载到 R0
LDR R0, [R1, R2] ; 将 R1+R2 地址的值加载到 R0
5. 自动增量/减量寻址(Auto-indexed Addressing)
这种寻址方式在基址变址寻址的基础上增加了自动更新功能。指令在访问数据后,会自动增加或减少基址寄存器中的值,从而实现指针的自动更新。这种方式对栈操作或循环中的数组访问特别有用。
示例:
LDR R0, [R1], #4 ; 将 R1 指向的地址的值加载到 R0,然后 R1 自增 4
6. 多寄存器寻址(Multiple Register Addressing)
这种方式一次性地访问多个寄存器,将其内容存储到内存中,或者从内存中加载多个寄存器的内容。常用于函数调用时保存和恢复多个寄存器。
示例:
STMFD SP!, {R0-R3} ; 将 R0-R3 的值压栈,并更新栈指针
LDMFD SP!, {R0-R3} ; 从栈中恢复 R0-R3 的值,并更新栈指针
7. 相对寻址(PC-relative Addressing)
在相对寻址中,目标地址相对于程序计数器(PC)提供的当前指令地址计算。这种方式在加载常量或跳转指令中较为常见。
示例:
LDR R0, [PC, #8] ; 从 PC+8 地址处加载数据到 R0
5.在复位后,ARM处理器处于何种模式?何种状态?
复位后,ARM 处理器会进入 管理模式(Supervisor Mode)[也叫特权模式]。
ARM 处理器复位后通常处于 ARM 状态,即可以执行 32 位长度的 ARM 指令。这是处理器的默认状态。在一些处理器中,可以通过复位配置选择进入 Thumb 状态(执行 16 位长度的 Thumb 指令),不过默认是 ARM 状态。
6.为什么FIQ的服务程序地址要位于0X1C?
尽可能快,省去跳转指令(FIQ的向量地址是异常中断向量表的最高地址,而异常中断向量表后跟的是程序代码,FIQ的中断服务程序紧接中断向量表存放,中断过程可以节省一条跳转指令)
当中断向量表起始地址为 0x00000000 时,FIQ 服务程序地址为 0x0000001C。
当中断向量表起始地址为 0xFFFF0000 时,FIQ 服务程序地址为 0xFFFF001C。
#牛客在线求职答疑中心##牛客解忧铺##嵌入式##嵌入式软开##面试题#该专栏是我整理的一些嵌入式软件笔面试常见的题目,在有一定计算机基础上,再过一遍该专栏的内容,对应届生校招来说基本上笔面试就没什么问题了! 有任何疑问可随时与我联系,一起交流一起进步。