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

ARM/THUMB模式下读取CPSR的正确方法及问题排查

ARMv7(Cortex-A7)下ARM/THUMB模式读取CPSR的问题

我在ARMv7(Cortex-A7)系统上工作,需要在ARM或THUMB模式下从C文件读取CPSR。最初使用如下内嵌汇编指令:

__asm__ volatile("mrs %0, CPSR\n" : "=r"(regval));

但以-mthumb编译并通过GDB运行时,regval值为0x60000010,与GDB显示的0x60000030不符。


编译选项补充说明

a) 指定THUMB模式编译

使用以下命令指定THUMB模式编译:

arm-linux-gnueabi-gcc -g2 backtrace.c -mcpu=cortex-a7 -static -mthumb -o tbacktrace

在qemu和GDB中运行得到不同值:

(gdb) p/x regval
$7 = 0x60000010
(gdb) p/x $cpsr
$8 = 0x60000030

疑问:为何mrs %0, CPSR\n读取的CPSR显示处于ARM模式,而代码实际为THUMB模式编译?

b) 不指定-mcpu=cortex-a7编译时

使用以下命令编译:

arm-linux-gnueabi-gcc -g2 backtrace.c -mthumb -o tbacktrace

出现如下错误:

$ arm-linux-gnueabi-gcc -g2 backtrace.c -mthumb -o tbacktrace
/tmp/ccOg2tlo.s: Assembler messages:
/tmp/ccOg2tlo.s:2256: Error: selected processor does not support `mrs r3,CPSR' in Thumb mode
/tmp/ccOg2tlo.s:2398: Error: selected processor does not support `mrs r3,CPSR' in Thumb mode

c) 默认编译(无-mcpu或-mthumb)

不指定-mcpu或-mthumb时,代码可正常编译运行,因此需找到能在ARM和THUMB模式下正确读取CPSR的方法。


反汇编代码验证运行模式

以-mthumb -mcpu=cortex-a7编译后,执行arm-linux-gnueabi-objdump -M force-thumb -d a.elf输出部分内容如下:

4000014c:       0ff0            lsrs    r0, r6, #31
4000014e:       e92d 0f30       stmdb   sp!, {r4, r5, r8, r9, sl, fp}
40000152:       ee30 3407       cdp     4, 3, cr3, cr0, cr7, {0}
40000156:       e210            b.n     4000057a <__aeabi_f2d+0x16>
40000158:       3ba3            subs    r3, #163        ; 0xa3
4000015a:       e1a0            b.n     4000049e <__adddf3+0x1f6>
4000015c:       001b            movs    r3, r3
4000015e:       0a00            lsrs    r0, r0, #8
40000160:       a000            add     r0, pc, #0      ; (adr r0, 40000164 <B_Loop1>)
40000162:       e3a0            b.n     400008a6 <__udivmoddi4+0x19a>

......
400002a8 <__adddf3>:
400002a8:       b530            push    {r4, r5, lr}
400002aa:       ea4f 0441       mov.w   r4, r1, lsl #1
400002ae:       ea4f 0543       mov.w   r5, r3, lsl #1
400002b2:       ea94 0f05       teq     r4, r5
400002b6:       bf08            it      eq
400002b8:       ea90 0f02       teqeq   r0, r2
400002bc:       bf1f            itttt   ne

结合Nate和Frant的评论,我认为代码确实运行在THUMB模式,无需通过CPSR的T位检测模式,此判断是否正确?


一种ARM/THUMB模式检测方法

参考评论后,我想到通过两次读取PC寄存器并检查差值检测模式:差值为2则是THUMB模式,差值为4则是ARM模式。代码如下:

register uint32_t pc1, pc2;
asm volatile("mov %0, pc\n mov %1, pc" : "=r"(pc1), "=r"(pc2));

以-Os优化、带/不带-mthumb编译后,该代码似乎能正确检测模式。


内容的提问来源于stack exchange,提问作者wangt13

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 02:05:18