1. 什么是立即数?如何判断某数是否是合法 12 位立即数?
- 立即数:在 ARM 指令中,直接包含在指令编码中的常数,无需从内存或寄存器加载。
- 12 位立即数合法性判断 :ARM 指令中的立即数由一个 8 位常数和一个 4 位循环右移位数(
rotate)编码而成。合法条件:该 32 位整数可以通过对一个 8 位无符号数,进行2×rotate位的循环右移得到(rotate取值为 0~15)。例如:0x3FC→ 可由 8 位0xFF循环右移 30 位得到 → 合法0x101→ 无法由 8 位常数循环右移得到 → 非法
2. b, bl, bx指令的区别
| 指令 | 全称 | 功能 | 特点 |
|---|---|---|---|
b |
Branch | 无条件跳转 | 仅修改 PC 寄存器,不保存返回地址 |
bl |
Branch with Link | 带链接的跳转 | 跳转前将当前 PC 值保存到lr(r14),用于函数调用后返回 |
bx |
Branch and Exchange | 带状态切换的跳转 | 跳转时根据目标地址的最低位切换指令集(0=ARM,1=Thumb) |
3. ARM 内核采用的栈是哪种栈?
ARM 内核默认使用满递减栈(Full Descending Stack, FD):
- 满栈 :栈指针
sp指向最后一个被压入栈的有效数据。 - 递减栈 :新数据压入时,
sp的值减小(向低地址方向增长)。这也是 ARM 架构中函数调用的标准栈模型。
4. CPSR 中条件标志位,分别在什么情况下被置位
CPSR(Current Program Status Register)包含 4 个主要条件标志位:
- N(Negative):运算结果最高位为 1 时置位,表示结果为负数(有符号数)。
- Z(Zero):运算结果为 0 时置位。
- C(Carry):无符号数加法产生进位,或减法产生借位时置位;移位操作时,最后移出的位会存入 C 位。
- V(Overflow):有符号数运算发生溢出时置位(如正数 + 正数 = 负数,负数 + 负数 = 正数)。
5. ARM 汇编调用 C 语言函数以及 C 语言函数调用汇编编写的函数,函数参数和返回值如何处理
遵循ARM AAPCS(Architecture Procedure Call Standard):
汇编调用 C 函数
- 参数传递 :
- 前 4 个参数依次放入
r0-r3,超过 4 个的参数压入栈(满递减栈)。 - 例如:
func(a,b,c,d,e)→r0=a,r1=b,r2=c,r3=d,e压栈。
- 前 4 个参数依次放入
- 返回值 :
- 32 位返回值存入
r0;64 位返回值存入r0+r1。
- 32 位返回值存入
- 调用流程 :使用
bl func调用,返回时通过bx lr回到汇编代码。
C 函数调用汇编函数
- 参数传递 :C 编译器自动将前 4 个参数放入
r0-r3,其余参数压栈,汇编函数直接从寄存器 / 栈中读取参数。 - 返回值 :汇编函数将结果存入
r0(或r0+r1),C 函数从r0获取返回值。 - 汇编函数要求 :需遵守寄存器使用规则(如
r4-r11为非易失性寄存器,使用前需保存到栈),并以bx lr返回。