我正在为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}^
尽管我明确没有存储 ANY sp寄存器。
我担心的是,虽然我大约15年前曾经做过很多汇编编码,但ARM代码对我来说是新的,我可能会误解一些东西!此外,如果我可以安全地忽略警告,有没有办法压制它们?
答案 0 :(得分:3)
ARM体系结构参考手册指出,用户寄存器的LDM / SMT中不允许写回。在异常返回的情况下允许它,其中pc
在寄存器列表中。
LDM(异常退货)
LDM{<amode>}<c> <Rn>{!},<registers_with_pc>^
LDM(用户注册)
LDM{<amode>}<c> <Rn>,<registers_without_pc>^
答案 1 :(得分:1)
术语“回写”是指不在注册表中是否存在SP
,而是指!
符号,这意味着该指令应该更新传输区域地址结束的SP
值。基本寄存器(SP)值将从当前模式使用,而不是用户模式,因此您仍然可以将用户模式SP值加载或存储到堆栈中。来自ARM ARM B9.3.6 LDM(用户寄存器):
在系统模式以外的PL1模式下,加载多个(用户寄存器) 从连续的内存位置加载多个用户模式寄存器 使用基址寄存器中的地址。加载的寄存器不能 包括PC。处理器正常读取基址寄存器值, 使用当前模式确定正确的Banked版本 寄存器。该指令无法回写到基址寄存器。
编码图通过将第21位(W,写回)指定为'(0)'来反映这一点,这意味着如果该位不为0,则结果是不可预测的。
所以解决办法就是不指定!
并在必要时手动递减或递增SP。