繁体   English   中英

如何在 ARM 或 THUMB 模式下写入 function 以读取 ARM CPSR?

[英]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 regvalp/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 值。

问题未解决?试试本站强大的搜索功能,搜索: 如何在 ARM 或 THUMB 模式下写入 function 以读取 ARM CPSR?
arm thumb mode code generation - gcc arm linux编译器

[英]arm thumb mode code generation — gcc arm linux compiler

我对ARM拇指模式有疑问。 GCC arm linux编译器是否自己生成拇指模式代码? 或者我们必须使用一些编译器指令告诉编译器生成拇指模式代码? ...

2012-12-08 11:12:34 1 4788   gcc / arm
在thumb模式下编译时的GCC arm指令模式

[英]GCC arm instruction mode when compiling in thumb mode

我想知道如果未指定-marm标志,使用--with-mode=thumb配置的 GCC 如何处理使用 ARM 模式部分的编译/组装代码。 那是: GCC 是用--with-mode=thumb编译的 不使用-marm编译程序(默认为拇指模式) 该程序的汇编部分使用 ARM 模式 我尝 ...

从Arm thumb2调用c函数时链接器错误

[英]Linker error while calling c function from Arm thumb2

我无法从手臂组件调用ac函数。 反之亦然。 拱是cortex-m3,木板已经到期。 编译器是gcc。 这是汇编代码: 这是C代码: 我得到的错误是- small_sample.So:在函数call_my_c_add': small_sample.S:12: un ...

Apple AS和ARM / Thumb ADDS指令

[英]Apple AS and ARM/Thumb ADDS instruction

我正在开发一个iPhone / iPad项目,我想在一些(不是全部)算术运算期间更新状态寄存器。 默认情况下,Xcode使用'Compile for Thumb',我不想更改它。 以下GCC内联汇编代码在ARM下工作正常,但在Thumb下导致编译错误:Thumb16模式下不支持指令 - ...

如何只编译ARM32二进制文件(没有拇指)

[英]How to compile ARM32 only binary (no thumb)

是否有GCC配置将生成仅包含ARM32代码的可执行文件? 我知道-marm开关告诉编译器不要生成Thumb代码,但它只适用于程序的用户代码 ,而初始化例程(例如_start , frame_dummy ,...)仍然包含Thumb指令。 我在Linux x86-64系统上使用Linaro交叉 ...

将默认 ARM gcc 选项更改为拇指

[英]Change default ARM gcc option to thumb

我想更改我的 Linux 机器中 ARM 工具链arm-linux-gnueabi-gcc的行为,编译后的代码将默认处于Thumb模式 - 与传递-mthumb标志相同。 我遇到了这个文档,它在--with-mode部分--with-mode准确地描述了我试图实现的目标。 但是,从他们的解释中我无 ...

修改 Compiler RT 汇编代码以编译 Arm Cortex M3/M4(CPSR/APSR 位操作)

[英]Modifying Comipler RT Assembly code to compile for Arm Cortex M3/M4 (CPSR/APSR bit manipulation)

我正在尝试从 Compiler RT 中获取数学例程,该程序使用 GCC 工具链用于 ARM Cortex M3/M4F 处理器(带有 fpu 的 armv7m 和 armv7em)。 除了以下函数中的两行代码( msr CPSR_f, ip和msr CPSR_f, #APSR_C )之外,我已经 ...

用于指定 ARM 或 Thumb 模式的 C 预处理器/编译器指令?

[英]C Preprocessor/compiler directives to specify ARM or Thumb modes?

当直接使用 ARM 汇编时,我可以使用.thumb和.thumb_func以及它们类似的 arm 指令来指示汇编器输出哪种指令。 开发 C 代码时是否有匹配的编译器指令? 我见过的 GCC 文档提到了各种命令行选项,以允许拇指和手臂代码在同一个二进制文件中工作,但输出看起来像是一个完整的二进制文件 ...

ARM Thumb-2,GCC,代码更改和`stmdaeq`指令

[英]ARM Thumb-2, GCC, code changes, and the `stmdaeq` instruction

我正在使用STM32F4(Cortex-M4)MCU,并使用arm-none-eabi-g ++进行编译(我正在使用C ++)。 我需要减少将二进制文件上传到MCU闪存所需的时间。 我已经知道可以通过在修改之间仅将更改上传到二进制文件来做到这一点。 但是,编译器正在生成一些有趣的代码, ...

编译为ARM我得到“错误:尝试在Thumb-only处理器上使用ARM指令”

[英]Compiling to ARM I get “Error: attempt to use an ARM instruction on a Thumb-only processor”

以下命令 在以下程序集文件testAsm.S : 为每条指令产生以下错误 错误:尝试在仅Thumb处理器上使用ARM指令 具体来说,下面是输出: 我试图为ARM进行编译。 为什么说仅拇指模式? 编辑:显然,将程序集文件从.arch armv7为. ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM