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 指令 # 实际上是可选的,例如movw 和 movt 没有错误:
movw r0, 1
movt r0, 0x1
但有以下错误:
movw r0, $1
movt r0, $0x1
ARM 参考手册
ARMv8-fb manual 本身在 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