2013-03-12 87 views
1

我正在为Raspberry Pi编写一些裸机代码,并且在Windows上收到来自ARM交叉汇编程序的意外警告。导致警告的指示是:GNU ARM汇编程序出现意外警告

stmdb sp!,{r0-r14}^ 

ldmia sp!,{r0-r14}^ 

的警告是:

警告:基址寄存器写回是不可预知的

我可排序的理解这一点,尽管'^'修饰符告诉处理器存储th e用户模式寄存器的副本,它不知道当指令执行时处理器将处于什么模式,并且似乎没有办法告诉它。我有点更关注以获取同样的警告:

stmdb sp!,{r0-r9,sl,fp,ip,lr}^ 

和:

ldmia sp!,{r0-r9,sl,fp,ip,lr}^ 

尽管我没有明确存储任何 SP寄存器。

我的问题是,虽然我大约15年前曾经做过很多汇编代码,但ARM代码对我来说是新的,我可能会误解某些东西!另外,如果我可以安全地忽略这些警告,是否有办法压制它们?

回答

1

术语 “回写” 指在寄存器列表中的存在或不存在的SP,但到!符号,这意味着该指令应该更新SP值与传输区域地址的结束。基址寄存器(SP)值将在当前模式下使用,而不是在用户模式下使用,因此您仍然可以将用户模式SP值加载或存储到堆栈中。从ARM ARM B9.3.6 LDM(用户登记):

在比系统模式下,加载多个(用户登记)使用的地址从一连续的内存位置 负载的多个用户模式寄存器以外的PL1模式基址寄存器。加载的寄存器不能包括PC在内的 。处理器通常使用当前模式读取基址寄存器值 ,以确定寄存器 的正确Banked版本。该指令不能回写到基址寄存器。

编码图通过将位21(W,写回)指定为'(0)'来反映这一点,这意味着如果该位不为0,则结果是不可预测的。

因此,解决方案只是不指定!,并在必要时手动递减或增加SP。

+0

啊,我错过了架构参考手册中的那一点,但我必须承认,我一直在使用ARM1176JZF-S技术参考手册来获取大部分信息,但似乎并没有详细讨论这个问题!我发现使用Google的警告(不是很多!)的所有解释都表示,警告是由于您正在对正在加载/存储的寄存器进行回写造成的。我知道回写是指更新基址寄存器。 – williamssimonp 2013-03-13 09:04:21

3

ARM体系结构参考手册指出在用户寄存器的LDM/SMT中不允许写回。在异常返回情况下允许使用,其中pc位于注册列表中。

LDM(异常返回)

LDM{<amode>}<c> <Rn>{!},<registers_with_pc>^ 

LDM(用户登记)

LDM{<amode>}<c> <Rn>,<registers_without_pc>^ 
+0

因此,要使用第一种形式从异常中返回,您必须执行没有写回的寄存器存储操作,更新堆栈指针,然后可以使用具有写回的版本返回!限制似乎有点奇怪,但我确信这是有原因的。至少它允许回写,如果PC正在加载,否则它将是无用的! – williamssimonp 2013-03-13 15:59:44