GNU gas
behavior for ARMv7 depends on .syntax
The docs say https://sourceware.org/binutils/docs-2.26/as/ARM_002dInstruction_002dSet.html#ARM_002dInstruction_002dSet :
Two slightly different syntaxes are support for ARM and THUMB instructions. The default, divided, uses the old style where ARM and THUMB instructions had their own, separate syntaxes. The new, unified syntax, which can be selected via the .syntax directive, and has the following main features:
- Immediate operands do not require a # prefix.
and https://sourceware.org/binutils/docs-2.26/as/ARM_002dChars.html#ARM_002dChars says:
Either '#' or '$' can be used to indicate immediate operands.
For ARMv8 #
is always optional
https://sourceware.org/binutils/docs-2.26/as/AArch64_002dChars.html#AArch64_002dChars documents:
The '#' can be optionally used to indicate immediate operands.
Test
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
Assemble:
arm-linux-gnueabi-as v7.S
aarch64-linux-gnu-as v8.S
Outcome: v8 suceeds, v7 fails on the divided
lines without #
:
v7.S:1: Error: immediate expression requires a # prefix -- `mov r0,1'
v7.S:2: Error: immediate expression requires a # prefix -- `mov r0,0x1'
TODO
Hmmm, but there are some v7 instructions for which #
is actually optional, e.g. there are no errors for movw
and movt
:
movw r0, 1
movt r0, 0x1
but there are errors for:
movw r0, $1
movt r0, $0x1
ARM reference manual
The ARMv8-fb manual has assembly/disassembly recommentations/requirements in itself, at C1.2 "Structure of the A64 assembler language":
The A64 assembly language does not require the # character to introduce constant immediate operands, but an
assembler must allow immediate values introduced with or without the # character. Arm recommends that an A64
disassembler outputs a # before an immediate operand.
Personal recommendation
Use .syntax unified
in your v7 code, and never use #
on any literal on either v7 or v8.
Unified syntax is newer and better, and those #
and $
signs are just more code noise.
The Linux kernel agrees with me: https://github.com/torvalds/linux/blob/v4.19/arch/arm/include/asm/unified.h#L23