我正在研究Arm架构参考手册ARMv7-A ARMv7-R版文档。当我读到本手册中的异常处理部分时,它让我感到困惑。当ARMv7-A架构实现采用IRQ异常时,问题在于如何确定LR值。
例如:假设处理器在0x_0000_1000的地址执行指令,而IRQ是taken.First,我们必须计算一些参数来计算LR。
然后,这里有两个在文档中提到的方法,用于确定在接受这个IRQ异常时的LR值。
E 237
。问题:两种方法在拇指集状态和arm集状态下计算的LR结果均为不同的( first method得到LR = 0x_0000_1006或LR = 0x_0000_1008,而第二方法E 263
我们得到E 164
LR = 0x_0000_1004或LR=0x_0000_1004E 265
)。哪一个是正确的,还是我的理解有任何问题?
发布于 2019-12-01 15:31:11
TL;DR - IRQ LR
将指向下一个指令来完成工作,就像通常不会中断运行的那样。否则,在存在中断的情况下,代码将不会执行相同的操作。
这是令人困惑的,因为ARM文档可能在许多不同的上下文中引用PC
,而且它们并不相同。
示例:假设处理器在0x_0000_1000地址处执行指令,并采用IRQ。首先,我们必须计算一些用于计算LR的参数。 首选返回地址,它是在这种情况下要执行的下一个指令的地址。因此,首选返回地址= 0x_0000_1002在拇指指令集或首选返回地址= 0x_0000_1004用于arm指令,set.preferred返回地址用于异常
这不对。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:‘。如果您遵循您的规则,这将增加中断延迟,因为在这种情况下不允许中断,或者中断会导致错误的代码。具体来说,您的链接显示要执行的下一条指令。
PC,它是程序计数器,保存当前程序address.In --在这种情况下,PC = 0x_0000_1004处于拇指指令状态,PC = 0x_0000_1008在arm指令state.how中计算PC。
在这里,你是混合概念。一种是使用像ldr r0, [pc, #42]
这样的值。计算偏移量时,必须将两个添加到当前ldr
指令中。实际的PC
不一定就是这个值。在某个时候(原始版本),ARM是一个两级管道。为了保持行为相同,随后的ARM cpus在计算ldr r0, [pc, #42]
类型地址时遵循两次领先的规则。然而,在CPU内部,实际的PC可能有很大的不同。上面的概念描述了与寻址一起使用的程序员可视PC
。
CPU将根据需要完成的工作(有时是基于配置)作出决定。例如,ldm sp!, {r0-r12}
可能需要一些时间才能完成。CPU可能决定中止此指令以保持中断延迟低。或者,它可以执行具有等待状态的12个存储器读取。LR_irq
将被设置为ldm
指令或下一个指令,这取决于它是否被中止。
https://stackoverflow.com/questions/59098139
复制相似问题