ARM汇编中立即数是否需要哈希值?

9

我一直在阅读由GCC生成的不同ARM汇编代码,并发现了一些规范中没有提到的内容。

movw    r0, #39784
movt    r0, 1

显然,第一个操作是将值39784移入r0的低16位,但movt操作符的'1'操作数是奇数,因为它没有哈希标记。我原本认为即时值需要哈希标记,这是有条件的吗?还是我漏掉了什么神奇的东西?


1
这是一个常见的话题; ARM汇编中的常量。以下是有关该主题的良好ARM博客。他们总是使用“#”符号。使用井号可能更具可移植性(到其他ARM汇编器)。然而,gccgas是亲密的。我不会将编译器输出作为编写汇编程序的指南。但是查看编译器正在执行的操作很有用。 - artless noise
2个回答

9

对于ARMv7,GNU gas的行为取决于.syntax

文档中提到https://sourceware.org/binutils/docs-2.26/as/ARM_002dInstruction_002dSet.html#ARM_002dInstruction_002dSet :

支持两种略有不同的ARM和THUMB指令语法。默认使用旧式样式,其中ARM和THUMB指令有自己的单独语法。可以通过.syntax指令选择新的统一语法,它具有以下主要特点:

  • 立即数操作数不需要#前缀。

https://sourceware.org/binutils/docs-2.26/as/ARM_002dChars.html#ARM_002dChars则说明:

要表示立即数操作数,可以使用“#”或“$”。

对于ARMv8,#始终是可选的

https://sourceware.org/binutils/docs-2.26/as/AArch64_002dChars.html#AArch64_002dChars文档:

“#”可选择用于指示立即操作数。

测试

Ubuntu 16.04,Binutils 2.26.1。

v7.S:

   /* These fail */
   mov r0, 1
   mov r0, 0x1

   /* These work */
   mov r0, #1
   mov r0, #0x1
   mov r0, $1
   mov r0, $0x1
.syntax unified
   mov r0, 1
   mov r0, #1
   mov r0, 0x1
   mov r0, #0x1
   mov r0, $1
   mov r0, $0x1

v8.S:

   mov x0, 1
   mov x0, #1
   mov x0, 0x1
   mov x0, #0x1

组装:

arm-linux-gnueabi-as v7.S
aarch64-linux-gnu-as v8.S

结果:v8 成功,v7 在没有 # 的 divided 行失败:

v7.S:1: Error: immediate expression requires a # prefix -- `mov r0,1'
v7.S:2: Error: immediate expression requires a # prefix -- `mov r0,0x1'

待办事项

嗯,但是对于某些v7指令,#实际上是可选的,例如movwmovt没有错误:

   movw r0, 1
   movt r0, 0x1

但是存在以下错误:

   movw r0, $1
   movt r0, $0x1

ARM参考手册

ARMv8-fb手册本身就包含有汇编/反汇编的建议/要求,位于C1.2“结构A64汇编语言”中:

A64汇编语言不需要“#”字符来引入常量立即操作数,但汇编器必须允许使用带或不带“#”字符引入的立即值。Arm建议A64反汇编器在立即操作数前输出“#”。

个人建议

在您的v7代码中使用.syntax unified,并且在v7或v8中不要对任何文字使用#

统一语法更新更好,那些#$标记只是更多的代码噪音。

Linux内核也支持我的观点: https://github.com/torvalds/linux/blob/v4.19/arch/arm/include/asm/unified.h#L23


@PeterCordes 谢谢你,Peter!在复制粘贴更新的过程中有点迷失了。现在应该已经修复了。 - Ciro Santilli OurBigBook.com
TODO: 需要注释并测试 ldr =# 只在 v7 上有效,因此最好对于 v7 和 v8 都只使用 = 而不带 # - Ciro Santilli OurBigBook.com

5
GNU汇编器不需要在ARM汇编代码中的立即操作数前加井号。你的印象是错误的。

谢谢!你有没有使用或不使用其中一个的原因?约定是什么? - Whyrusleeping
我不知道是否有一个被广泛接受的惯例。但你应该保持一致性。 - user1619508

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接