ARM1176JZF-S架构下Banked寄存器访问失败问题求助
问题解决:ARM1176JZF-S数据中止异常处理中的SPSR访问及编译架构问题
一、核心错误:跨模式访问Banked寄存器
你对技术手册的理解存在偏差:高特权模式仅能访问自身模式的Banked寄存器,无法直接跨模式读取其他异常模式的Banked寄存器(比如在Supervisor模式下直接读取SPSR_abt)。ARMv6架构明确规定,只有CPU处于对应异常模式时,才能直接读取该模式的SPSR。
你的代码中,进入数据中止异常后立刻通过cpsid if, #OPERATING_MODE_SVC切换到了Supervisor模式,此时已离开Abort模式,自然无法执行mrs r2,SPSR_abt指令。
修正方案
在切换到Supervisor模式之前,先读取Abort模式的SPSR并暂存到寄存器中:
.globl _data_abort_handler_entry _data_abort_handler_entry: sub lr, lr, #0x8 ; 关键:此时仍处于Abort模式,直接读取SPSR_abt mrs r2, SPSR_abt srsdb sp!, #OPERATING_MODE_SVC cpsid if, #OPERATING_MODE_SVC push {r0-r12} push {lr} and r1, sp, #0x4 // Aligning the stack pointer sub sp, sp, r1 push {r1} mrc p15, 0, r0, c6, c0, 0 // Get Fault Address Registers value mrc p15, 0, r1, c5, c0, 0 // Get the Data Fault Status Registers value blx _data_abort_handler pop {r1} add sp, sp, r1 pop {lr} pop {r0-r12} rfeia sp!
二、ARM官方编译器不识别armv6kz的问题
ARM官方编译器(如ARMclang)对旧架构的支持更倾向于指定具体CPU型号而非架构版本:
- 直接使用
-mcpu=arm1176jzf-s即可,该参数会自动匹配对应的armv6kz架构,无需手动指定-march=armv6kz。 - 若新版本编译器已放弃ARMv6支持,可降级到ARM Compiler 6.16及更早版本,这些版本仍兼容ARMv6系列CPU。
三、gcc编译选项修正
你的编译选项中-lgcc属于链接阶段参数,不能和-c(仅编译不链接)同时使用。修正后的编译命令:
arm-none-eabi-gcc -mcpu=arm1176jzf-s -fpic -ffreestanding -nostdlib -c -O2 your_file.s
链接时再添加-lgcc:
arm-none-eabi-ld -o your_output.elf ... -lgcc
内容的提问来源于stack exchange,提问作者arongeo
相关产品推荐
相关产品推荐

