什么是当前的执行模式/异常级别等?

时间:2015-08-03 12:43:46

标签: exception-handling arm arm64

我是ARMv8架构的新手。我有以下基本问题:

  1. 我怎么知道当前执行模式AArch32或AArch64是什么?我应该阅读CPSR或SPSR以确定这一点吗?

  2. 目前的例外情况EL0 / 1/2/3是什么?

  3. 一旦出现异常,我是否可以读取任何寄存器以确定我是否处于Serror / Synchronous / IRQ / FIQ异常处理程序中。

  4. TIA。

2 个答案:

答案 0 :(得分:5)

  1. 32位和64位的汇编指令及其二进制编码完全不同。因此,您当前所处的模式是您/编译器在编译期间需要知道的内容。在运行时检查它们没有意义。对于C,C ++检查可以在编译时(#ifdef)通过编译器提供的宏完成,如armclang__aarch64__为64位,__arm__为32位提供的宏
  2. 取决于执行模式:
    • aarch32:MRS <Rn>, CPSR将当前状态读入寄存器编号n。然后提取包含当前模式的位3:0。
    • aarch64:MRS <Xn>, CurrentEL将当前EL读入寄存器编号n
  3. 简答:你不能。长答案:假设是通过代码结构和任何用户定义变量的状态,您已经知道自己在做什么。即你是通过常规代码还是通过例外来代码中的位置。

答案 1 :(得分:1)

aarch64 C代码:

register uint64_t x0 __asm__ ("x0");
__asm__ ("mrs x0, CurrentEL;" : : : "%x0");
printf("EL = %" PRIu64 "\n", x0 >> 2);

手臂C代码:

register uint32_t r0 __asm__ ("r0");
__asm__ ("mrs r0, CPSR" : : : "%r0");
printf("EL = %" PRIu32 "\n", r0 & 0x1F);
但是,如ARMv8手册C5.2.1“ CurrentEL,当前异常级别”部分“可访问性”中所示,不能从EL0读取

CurrentEL。试图在Linux用户环境中运行它会引发SIGILL。但是我想你可以捕捉到那个信号...

可从EL0读取CPSR。

在QEMU和gem5 with this setup上进行了测试。