ARM分段寄存器

3
在ARM中,有一个叫做“分段寄存器”的概念。在阅读关于什么是“分段”和各种其他资源的很多问题及其答案时,我得到了这个定义: 寄存器分段是指在同一地址上提供多个寄存器的副本。并非所有寄存器都可以同时看到。
但我的疑问是,如何创建多个寄存器的副本呢?因为我们的核心只有单个寄存器文件。如果有另一种模式,它将获得新的分段寄存器副本,其中不含任何数据,也不会访问另一种模式寄存器的数据。 那么这个寄存器的副本是如何创建的呢?
2个回答

3
注册银行是指在同一地址提供多个寄存器的功能。并非所有寄存器都可以同时查看。 这个说法有些正确。然而,寄存器没有“传统地址”。大多数ARM指令或“二进制编码”将寄存器作为源或目标参数。有十六个基本寄存器,因此每个寄存器需要四位二进制指令。一个典型的指令需要12位(32位中的12位)来描述三个寄存器(两个源寄存器和一个目标寄存器)。指令中的这些位是上面定义中的“地址”。 但我在这里的问题是如何创建多个寄存器的副本。因为我们的核心只有单个寄存器文件。如果有另一种模式,它将获得新的银行寄存器副本,该副本不包含任何数据,并且不会访问另一种模式寄存器的数据。那么这个寄存器的副本是如何创建的呢? 它们不是动态“创建”的。分段寄存器是核心“寄存器文件”的一部分,始终存在。问题在于,典型的指令无法访问某些分段寄存器,除非发生“模式切换”。这可能是从用户到IRQ模式,或从普通模式到具有TrustZone的安全世界。
在不同模式下运行相同的代码可能会访问不同(分段)的寄存器。这样,用户代码从不影响IRQ堆栈,反之亦然。也许更重要的是,如果在IRQ开始和结束时没有进行仔细的上下文保存,IRQ代码可能会破坏非分段用户寄存器。
请参见:ARM上访问分段寄存器,了解如何访问这些不同的寄存器。
新的ARMv7指令mrs r2,sp_svc打破了这个分段寄存器规则,并允许直接访问分段寄存器而无需切换模式。目的是为了让上下文切换代码轻松访问分段寄存器以进行保存和恢复,而无需切换模式。
传统的指令ldm rN, {sp,lr}^允许在不切换模式的情况下保存用户堆栈指针和链接寄存器。同样,这具有特殊的编码(或根据您的定义进行寻址)。
银行业务也使用TrustZone中的CP15系统寄存器。TrustZone监视模式和分行IFSR... 对于任何研究ARM“银行”概念的人来说可能是有趣的,这个概念与寄存器银行是相同的。

你的回答解决了我的疑惑...我之前一直困惑于寄存器文件只包含16个寄存器。 - sam1006
代表belwizdadi Med:解释非常混乱:寄存器的多个副本存储在同一地址...您能否用汇编语言编写这个“sharabia”,以便我们知道涉及哪些部分以及如何操作? - artless noise
并没有所谓的“地址”。它是操作码二进制位中的一段。根据CPU当前的模式,访问不同的“内存”或寄存器。寄存器只是物理上位于CPU逻辑内部的超快速内存。请参见链接:在ARM上显式访问分行寄存器获取一些示例代码或TZ链接。另外:维基百科上的寄存器文件切换,其中有几种翻译。 - artless noise

3
我数了一下,传统Arm需要31个寄存器。其中几个是用于FIQ模式的r13和r14。首先,你混淆了任务和模式。在应用程序层面,任务将共享同一组寄存器,没有银行交易,在切换任务时必须保存寄存器,操作系统为此分配内存,并且对于每次任务切换,都会保存旧任务的寄存器并恢复下一个任务的寄存器。
至于寄存器银行业务,例如有多个r13。对于对寄存器的每次访问,不仅仅是对寄存器文件的简单偏移量,还有其他的输入,例如:
unsigned int get_r13 ( unsigned int mode )
{
switch(mode)
{
case SYS: return r13_sys;
case SVC: return r13_svc;
case ABT: return r13_abt;
case UND: return r13_und;
case IRQ: return r13_irq;
case FIQ: return r13_fiq;
}
}

但在逻辑上,尽管逻辑看起来可能非常相似,但他们会将模式位逻辑地转换为寄存器文件中的一些地址位或这些位的组合。

单个寄存器文件并不意味着寄存器文件中只有16个寄存器(r0-r15,不包括cpsr等),实际上寄存器文件中有31个或更多,具体取决于它是否包含*PSR寄存器。


但问题是当模式切换发生时,该模式将获取R13寄存器,这是分组寄存器...好吗?那么在先前保存内容时会发生什么? - sam1006
有几个不同的寄存器,你访问哪一个取决于模式,当你返回到之前的模式时,你就可以像上面的伪代码所示那样访问该分行寄存器的内容。如果你写入 r14_svc,一些值,然后切换模式并读/写 r14_irq 一段时间,然后回到 svc 模式,你就可以访问留在该分行寄存器中的 r14_svc,它不会消失。 - old_timer
我理解你所说的数据不会被损坏,这是正确的,之前的模式数据不会被破坏,但我不明白新模式如何通过架构方式而非编码方式获取r13寄存器的全新副本。 - sam1006
引导程序代码或引导加载程序会遍历每个模式并设置堆栈,这是由软件完成的。除了用户模式外,您可以写入cpsr以手动更改模式,然后只需写入r13,更改模式再写入r13等。这可能是系统模式和用户模式共享寄存器的原因之一。 - old_timer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接