我一直在努力阅读gcc生成的一些不同的手臂汇编代码,我发现了一些我在规范中找不到的东西。
movw r0, #39784
movt r0, 1
显然第一个是将值39784移动到底部16位或r0,但是'1'的movt的操作数是奇数,因为它之前没有哈希值,而且我认为立即值需要哈希。在某些情况下它是否可选?还是我错过了一些神奇的东西?
答案 0 :(得分:3)
GNU汇编程序在ARM汇编代码的立即操作数之前不需要octothorpe。您的印象不正确。
答案 1 :(得分:2)
ARMv7的GNU gas
行为取决于.syntax
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
个人推荐
在v7代码中使用.syntax unified
,切勿在v7或v8的任何文字上使用#
。
统一语法更新,更好,而#
和$
符号只是更多的代码噪音。
Linux内核同意我的观点:https://github.com/torvalds/linux/blob/v4.19/arch/arm/include/asm/unified.h#L23