关于 GNU ARM 汇编程序的意外警告
Posted
技术标签:
【中文标题】关于 GNU ARM 汇编程序的意外警告【英文标题】:Unexpected warning on GNU ARM Assembler 【发布时间】:2013-02-28 17:12:43 【问题描述】:我正在为 Raspberry Pi 编写一些裸机代码,并且收到来自 Windows 上的 ARM 交叉汇编程序的意外警告。导致警告的说明是:
stmdb sp!,r0-r14^
和
ldmia sp!,r0-r14^
警告是:
警告:基址寄存器的写回不可预测
我可以这样理解,虽然 '^' 修饰符告诉处理器存储寄存器的用户模式副本,但它不知道当指令执行时处理器将处于什么模式并且没有' t 似乎是一种告诉它的方式。我有点担心收到相同的警告:
stmdb sp!,r0-r9,sl,fp,ip,lr^
和:
ldmia sp!,r0-r9,sl,fp,ip,lr^
尽管我明确不存储 ANY sp 寄存器。
我担心的是,尽管大约 15 年前我曾经做过很多汇编代码,但 ARM 代码对我来说是新的,我可能会误解一些东西!另外,如果我可以安全地忽略这些警告,有没有办法抑制它们?
【问题讨论】:
【参考方案1】:术语“写回”不是指SP
在寄存器列表中的存在或不存在,而是指!
符号,这意味着该指令应该更新SP
值与传输区地址结束。基址寄存器 (SP) 值将用于当前模式,而不是用户模式,因此您仍然可以将用户模式 SP 值加载或存储到堆栈中。来自 ARM ARM B9.3.6 LDM(用户寄存器):
在系统模式以外的 PL1 模式下,加载多个(用户寄存器) 从连续的内存位置加载多个用户模式寄存器 使用来自基址寄存器的地址。加载的寄存器不能 包括电脑。处理器正常读取基址寄存器值, 使用当前模式来确定正确的 Banked 版本 登记。该指令不能写回基址寄存器。
编码图通过将第 21 位(W,写回)指定为“(0)”来反映这一点,这意味着如果该位不为 0,则结果是不可预测的。
所以解决方案就是不指定!
,必要时手动递减或递增SP。
【讨论】:
啊,我错过了架构参考手册中的那一点,尽管我必须承认我一直在使用 ARM1176JZF-S 技术参考手册来获取我的大部分信息,但这似乎并不适用这么详细!我使用 Google 发现的警告的所有解释(不是很多!)都说警告是因为您正在写回正在加载/存储的寄存器。我理解写回是指基址寄存器的更新。【参考方案2】:ARM 架构参考手册说在用户寄存器的 LDM/SMT 中不允许写回。它在异常返回情况下是允许的,其中pc
在寄存器列表中。
LDM(异常返回)
LDM<amode><c> <Rn>!,<registers_with_pc>^
LDM(用户注册)
LDM<amode><c> <Rn>,<registers_without_pc>^
【讨论】:
所以,要使用第一种形式从异常中返回,您必须在不回写的情况下存储寄存器,更新堆栈指针,然后您可以使用带有回写的版本返回!这个限制似乎有点奇怪,但我相信这是有原因的。至少在加载 pc 时允许 writeback,否则就没用了!以上是关于关于 GNU ARM 汇编程序的意外警告的主要内容,如果未能解决你的问题,请参考以下文章