【问题标题】:Usage of the .W suffix in ARM assembler [duplicate]在 ARM 汇编程序中使用 .W 后缀 [重复]
【发布时间】:2015-10-25 13:48:26
【问题描述】:

我正在阅读指令集手册,我想知道 .W 后缀。

手册说:

在某些情况下,可能需要指定 .W 后缀,因为 例如,如果操作数是指令或文字数据的标签, 与分支指令的情况一样。这是因为汇编器 可能不会自动生成正确的大小编码。

我想不出有什么理由需要覆盖汇编器的默认编码。到目前为止,我尝试过的东西在没有.W 的情况下总是编译得很好。

他们是否真的添加了一种特殊的语法来克服汇编器中可能存在的错误(也许同时修复了)?

您能否提供一些我必须明确使用 .W(Cortex-M3 上的 Thumb2)的示例。

【问题讨论】:

  • 它可以帮助汇编器清楚地了解何时可以在 thumb 和 thumb2 之间进行选择。只需查看 ARM ARM 中的 B 编码/指令,您就可以看出区别。根据条件或无条件,所有变体都提供 8 位或 11 位立即数。 thumb2 扩展根据条件提供 16 位或 21 位立即数。通过使用 .w 您表明您想要 thumb2 而不是让汇编程序猜测。但是,如果汇编程序在这种情况下猜错了,我会称之为错误。
  • 对于组装时的已知标签,它知道它必须编码什么。对于外部标签,它可以烧掉半字以减少链接器出现问题或必须添加东西的变化。但是如果需要,gcc 链接器至少现在添加了一个蹦床以到达所需的地址。在这种情况下(或在编写手册时),arm assembler/linker 可能不如 gnu 好
  • 如果您特别希望 thumb2 扩展名用于出于某种原因,您使用 .w 强制执行此操作
  • thumb2 扩展可以在 m0、m0+、m1、m3、m4、m7 和 cortex-a 上找到,或者至少在其中一些上。什么数字不同。例如,armv6m(皮质 m0/m1)没有用于分支的 thumb2 扩展。但是 m3/m4(/m7) 可以。
  • @artlessnoise 有单独的“X 是什么?”与“我什么时候应该使用 X?”问题已经是一种常见的模式,因为有一个明确的逻辑区别。 add/addw 是可怕的指令特定语法的一个特例——.n/.w 可以被普遍回答(这里的问题和回答都没有提到特定的助记符,也不需要)。跨度>

标签: assembly arm thumb


【解决方案1】:

.W 后缀在语法中仍然是必要的,即使大多数人永远不会显式使用它,以保持反汇编任何有效代码并将结果源返回的行为汇编器再次产生完全相同的指令。因此,每个有效的指令编码都必须有某种方式在语言中明确表示,即使它不是汇编程序默认为基本助记符和操作数选择的首选方式。当然,因为它存在于语法中,所以您不必直接编写机器代码或修补二进制文件即可获得这些编码。

现在,在最终二进制文件中需要非首选编码有各种深奥的原因——比如调整指令对齐、使用代码作为数据等——但最不疯狂的一个可能是重定位。如果您有一个外部符号的分支,或不同部分中的符号,汇编器不一定知道该符号将结束多远。因此,它必须在发出可能最终无法链接的窄指令或如果目标足够接近最终可能会浪费代码空间的宽指令之间做出选择。 GNU as 和 armasm 似乎都支持后者,尽管不难想象一些专门的嵌入式汇编程序出于大小原因默认使用前者。

运行时重定位是一个更强有力的论据:您有一个分支或文字负载, 在组装时解决,但您可能希望在某些情况下进行热补丁以定位其他内容。即使原始目标位于窄编码范围内,这也可能需要额外的宽编码范围。

【讨论】:

  • 我觉得前几句太强了。我的意思是它应该在指令级别上工作,但声称你会得到相同的二进制 blob 可能太过分了。至少你不能仅仅因为 .W 后缀的使用而做出这种声明。
  • @auselen 没错,“目标文件”太宽泛了,没有当时我脑海中的特定上下文。尽管如此,就指令而言,让反汇编/重组是幂等的肯定是专门为该语言设计的功能。另请参阅没有人知道的修改后立即常量的奇怪的两部分语法。
  • 我同意,你在这里有一个很好的解释,只是早期的句子可能会误导不太了解的人。否则一如既往的好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-26
相关资源
最近更新 更多