You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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型号而非架构版本:

  1. 直接使用-mcpu=arm1176jzf-s即可,该参数会自动匹配对应的armv6kz架构,无需手动指定-march=armv6kz。
  2. 若新版本编译器已放弃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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:35:57