1

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

stmdb sp!,{r0-r14}^

ldmia sp!,{r0-r14}^

警告是:

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

我可以这样理解,虽然'^'修饰符告诉处理器存储寄存器的用户模式副本,但它不知道执行指令时处理器将处于什么模式并且似乎没有是一种方式来告诉它。我更担心会收到相同的警告:

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

和:

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

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

我担心的是,尽管大约 15 年前我曾经做过很多汇编代码,但 ARM 代码对我来说是新的,我可能会误解一些东西!另外,如果我可以安全地忽略这些警告,有没有办法抑制它们?

4

2 回答 2

3

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

LDM(异常返回)

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

LDM(用户寄存器)

LDM{<amode>}<c> <Rn>,<registers_without_pc>^
于 2013-03-12T23:22:35.010 回答
1

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

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

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

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

于 2013-03-13T00:24:50.320 回答