ARMv7-A架构实现出现IRQ异常时如何计算LR值

How to calculate the LR value when ARMv7-A architecture implementation takes an IRQ exception

最近在研究Arm Architecture Reference Manual ARMv7-A ARMv7-R edition文档。当我读到本手册的异常处理部分时,我感到很困惑。 问题是当ARMv7-A架构实现出现IRQ异常时如何确定LR值

例子:假设处理器正在执行地址0x_0000_1000的指令,IRQ是taken.First,我们需要计算一些参数来计算LR。

  1. preferred return address,这是本例中下一条要执行的指令的地址。所以 preferred return address = 0x_0000_1002 in thumb instruction set 或者 preferred return address = 0x_0000_1004 用于 arm 指令集。preferred return address for the exception
  2. PC,这是程序计数器,保存当前程序 address.In 这种情况下,PC = 0x_0000_1004在拇指指令状态或PC = 0x_0000_1008在手臂指令状态。how to calculate PC

那么,这里有文档中提到的2种方法来决定这个IRQ异常时的LR值

  1. 通过使用 首选 return 地址LR = preferred return address + offset 取决于指令集状态时异常是 taken.In 这种情况 LR = 0x_0000_1002 + 4 在拇指指令状态或 LR = 0x_0000_1004 + 4在arm指令状态。Offsets applied to Link value for exceptions taken to PL1 modes
  2. 通过使用 PCLR = PC-0 如果在 thumb 指令集中或 LR = PC-4 当在 arm 指令中 set.In 这种情况 LR = 0x_0000_1004 - thumb 指令集中的 0LR = 0x_0000_1008 - 4 在 arm 指令状态。 Pseudocode description of taking the IRQ exception

问题:两种方法计算出的LR结果在拇指组状态和手臂组状态下都不同(with 第一种方法我们得到LR = 0x_0000_1006或LR = 0x_0000_1008,但是第二种方法 我们得到 LR = 0x_0000_1004 或 LR = 0x_0000_1004)。哪一个是正确的或者我的理解有什么问题?

TL;DR - IRQ LR 将指向下一条指令以完成工作,通常 运行 没有中断。否则,代码将不会在存在中断的情况下执行相同的操作。

这令人困惑,因为 ARM 文档可能在许多不同的上下文中引用 PC,而且它们并不相同。


EXAMPLE:Suppose that the processor is executing an instruction at the address of 0x_0000_1000 and an IRQ is taken. First, we have to calculate some parameters to be used to calculate the LR.

preferred return address,which is the Address of next instruction to execute in this case. So preferred return address = 0x_0000_1002 in thumb instruction set or preferred return address = 0x_0000_1004 for arm instruction set.preferred return address for the exception

这是不正确的。 ARM cpu 有一个流水线,它认为已经完成的最后一条指令是 下一条指令 。以这个序列为例,

     0: cmp r1, #42
     1: bne 4f          ; interrupt happens as this completes.
     2: add r2, r2, #4
     3: b   5f
     4: sub r2, r2, #2
     5: ; more code.

如果中断发生在标签“1:”发生时,下一条指令将是“2:”或“4:”。如果您遵循您的规则,这将通过在这种情况下不允许中断来增加中断延迟,或者中断会导致不正确的代码。具体来说,您的 link 表示 下一条要执行的指令

PC,which is the program counter and holds the current program address.In this case, PC = 0x_0000_1004 in thumb instruction state or PC = 0x_0000_1008 in arm instruction state.how to calculate PC

你在这里混淆了概念。一种是当您使用 ldr r0, [pc, #42] 这样的值时。当你计算偏移量时,你必须在当前的ldr指令上加上两个。实际的PC不一定是这个值。在某些时候(原始版本),ARM 是一个两级流水线。为了保持行为相同,后续的 ARM cpu 在计算 ldr r0, [pc, #42] 类型地址时遵循前两位的规则。但是,实际的PC里面可能会有很大的不同CPU。上面的概念描述了程序员可见的 PC 用于寻址。

CPU 将根据配置决定要完成的工作。例如,ldm sp!, {r0-r12} 可能需要一些时间才能完成。 CPU 可能会决定中止该指令以保持较低的中断延迟。或者,它可以执行 12 次可能具有等待状态的内存读取。 LR_irq 将被设置为 ldm 指令或下一条指令,具体取决于它是否被中止。