
[英]arm thumb mode code generation — gcc arm linux compiler
我对ARM拇指模式有疑问。 GCC arm linux编译器是否自己生成拇指模式代码? 或者我们必须使用一些编译器指令告诉编译器生成拇指模式代码? ...
[英]How to write a function to read ARM CPSR in either ARM or THUMB mode?
提示:本站为国内最大中英文翻译问答网站,提供中英文对照查看,鼠标放在中文字句上可显示英文原文。
我正在使用 ARMv7 (Cortex-A7) 系统,我想在 ARM 模式或 THUMB 模式下从 C 文件读取 CPSR。
首先,我在 C function 中使用了嵌入式 ASSEMBLY 指令,如下所示,
__asm__ volatile("mrs %0, CPSR\n" : "=r"(regval));
当我用 -mthumb 编译 C 文件并用 GDB 运行代码时,它显示 regval 是 0x60000010,这不是 GDB 显示的 0x60000030!
那么如何写一个function在ARM或THUMB模式下读取CPSR呢?
a) 使用以下命令行构建代码以指定 THUMB 模式。
arm-linux-gnueabi-gcc -g2 backtrace.c -mcpu=cortex-a7 -static -mthumb -o tbacktrace
使用 qemu 和 GDB 运行 tbacktrace,我得到了不同的值,
(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 的情况下构建代码,代码可以很好地构建和运行。 所以我认为应该有一些其他方法可以在 ARM 和 THUMB 模式下获得正确的CPSR。
CPSR.c
:
#include <stdint.h>
int main(int argc, char* argv[]) {
uint32_t regval;
asm volatile("mrs %0, CPSR" : "=r"(regval));
return regval;
}
如果您不使用-mcpu=cortex-a7
,您的编译器将默认使用另一个 CPU:
/opt/arm/10/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gcc -O0 -nostartfiles -nostdlib -Wl,--section-start=.text=0x80800000 -S CPSR.c
cat CPSR.s
.cpu arm7tdmi
.arch armv4t
ARM7TDMI-S 于 2001 年推出,正如您的编译器所指出的,似乎不支持不支持 Thumb 模式下的mrs r3,CPSR
。 因此,您必须指定-mcpu=cortex-a7
:
/opt/arm/10/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gcc -mcpu=cortex-a7 -O0 -nostartfiles -nostdlib -Wl,--section-start=.text=0x80800000 -S CPSR.c
cat CPSR.s
.cpu cortex-a7
.arch armv7-a
CPU 和架构现在符合预期。
在真实硬件上测试您的代码 - 运行u-boot
的 Cortex-A7 - 在 Arm 和 Thumb 模式下:
Arm:
/opt/arm/10/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gcc -O0 -mcpu=cortex-a7 -marm -nostartfiles -nostdlib -Wl,--section-start=.text=0x80800000 -o CPSR-arm.elf CPSR.c
/opt/arm/10/gcc-arm-none-eabi-10.3-2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000080800000
/opt/arm/10/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-objcopy -O srec CPSR-arm.elf CPSR-arm.srec
/opt/arm/10/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-objdump -j .text -D CPSR-arm.elf
CPSR-arm.elf: file format elf32-littlearm
Disassembly of section .text:
80800000 <main>:
80800000: e52db004 push {fp} ; (str fp, [sp, #-4]!)
80800004: e28db000 add fp, sp, #0
80800008: e24dd01c sub sp, sp, #28
8080000c: e50b0010 str r0, [fp, #-16]
80800010: e50b1014 str r1, [fp, #-20] ; 0xffffffec
80800014: e50b2018 str r2, [fp, #-24] ; 0xffffffe8
80800018: e10f3000 mrs r3, CPSR
8080001c: e50b3008 str r3, [fp, #-8]
80800020: e51b3008 ldr r3, [fp, #-8]
80800024: e1a00003 mov r0, r3
80800028: e28bd000 add sp, fp, #0
8080002c: e49db004 pop {fp} ; (ldr fp, [sp], #4)
80800030: e12fff1e bx lr
I.MX7d 运行 u-boot:
# loads
## Ready for S-Record download ...
## First Load Addr = 0x80800000
## Last Load Addr = 0x80800033
## Total Size = 0x00000034 = 52 Bytes
CACHE: Misaligned operation at range [80800000, 80800034]
## Start Addr = 0x80800000
# go 0x80800000
## Starting application at 0x80800000 ...
## Application terminated, rc = 0x200000D3
拇指:
/opt/arm/10/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-gcc -O0 -mcpu=cortex-a7 -mthumb -nostartfiles -nostdlib -Wl,--section-start=.text=0x80800000 -o CPSR-thumb.elf CPSR.c
/opt/arm/10/gcc-arm-none-eabi-10.3-2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000080800000
/opt/arm/10/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-objcopy -O srec CPSR-thumb.elf CPSR-thumb.srec
/opt/arm/10/gcc-arm-none-eabi-10.3-2021.10/bin/arm-none-eabi-objdump -j .text -D CPSR-thumb.elf
CPSR-thumb.elf: file format elf32-littlearm
Disassembly of section .text:
80800000 <main>:
80800000: b480 push {r7}
80800002: b087 sub sp, #28
80800004: af00 add r7, sp, #0
80800006: 60f8 str r0, [r7, #12]
80800008: 60b9 str r1, [r7, #8]
8080000a: 607a str r2, [r7, #4]
8080000c: f3ef 8300 mrs r3, CPSR
80800010: 617b str r3, [r7, #20]
80800012: 697b ldr r3, [r7, #20]
80800014: 4618 mov r0, r3
80800016: 371c adds r7, #28
80800018: 46bd mov sp, r7
8080001a: bc80 pop {r7}
8080001c: 4770 bx lr
I.MX7d 运行 u-boot:
# loads
## Ready for S-Record download ...
## First Load Addr = 0x80800000
## Last Load Addr = 0x8080001D
## Total Size = 0x0000001E = 30 Bytes
CACHE: Misaligned operation at range [80800000, 8080001e]
## Start Addr = 0x80800000
#
# go 0x80800001
## Starting application at 0x80800001 ...
## Application terminated, rc = 0x200000D3
最重要的是,两个版本都为 CPSR 返回了相同的值,即0x200000D3
。
对于问题
如何在 ARM 或 THUMB 模式下写入 function 以读取 ARM CPSR?
答案将是:你做的方式。 询问为什么p/x regval
和p/x $cpsr
没有返回相同的值应该是另一个问题的主题,可能在 GDB 论坛上。
该指令按设计和记录工作。
不一致的是bit 5,根据ARMv7-A Architecture Reference Manual ,它是T位,表示处理器是否在Thumb state。它是“执行state位”之一。 在该页面的下方,在“访问执行 state 位”下,它说:
当由 MRS 指令读取时,执行的 state 位(E 位除外)为 RAZ [读为零]。
所以mrs rN, CPSR
屏蔽掉了这些位。 我不确定为什么要这样设计。 但原则上您应该已经知道您是否在 Thumb state 中,因此实际上没有必要从 CPSR 中读取此信息。
另一方面,gdb 没有从mrs rN, CPSR
获得它的 CPSR 值。 我没有检查过,但我想会发生什么:当你的程序遇到断点时,会产生一个异常。 这会导致 CPSR 被保存到 SPSR(不屏蔽任何位),并且内核的异常处理程序从那里检索它,并将其作为已保存的进程上下文的一部分与寄存器值一起存储。 等等。保存的上下文通过适当的系统调用(例如ptrace(2)
)可供调试器使用,这就是它能够显示寄存器内容等的方式。 特别是,它获取在断点处保存且未屏蔽的 CPSR 值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.