ARM 程序集中的立即数是不是需要散列?

Posted

技术标签:

【中文标题】ARM 程序集中的立即数是不是需要散列?【英文标题】:Is the hash required for immediate values in ARM assembly?ARM 程序集中的立即数是否需要散列? 【发布时间】:2014-03-06 08:21:56 【问题描述】:

我一直在努力阅读由 gcc 生成的一些不同的 arm 汇编代码,我遇到了一些我无法在规范中找到的东西。

movw    r0, #39784
movt    r0, 1

显然第一个是将值 39784 移动到底部的 16 位或 r0 中,但是 movt 的操作数 '1' 是奇数,因为它之前没有散列,我的印象是立即值需要散列.在某些情况下它是可选的吗?还是我错过了什么神奇的东西?

【问题讨论】:

这是一个常见的话题; ARM 汇编程序中的常量。这是关于该主题的good ARM blog。他们总是使用“哈希”。使用散列可能更便于移植(对于其他 ARM 汇编程序)。但是,gccgas 是亲密的。我不一定会使用编译器输出的内容作为编写汇编程序的指南。看看编译器在做什么很有用。 【参考方案1】:

对于 ARM 汇编代码,GNU 汇编器不需要在直接操作数之前有八字。您的印象不正确。

【讨论】:

谢谢!有什么理由你会或不会使用一个吗?约定是什么? 我不知道有一个公认的约定。不过,您当然应该保持一致。【参考方案2】:

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 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

【讨论】:

@PeterCordes 谢谢彼得!在复制粘贴更新舞蹈中有点迷失。现在应该修好了。 TODO:推荐并测试 ldr =# 仅适用于 v7,因此最好在 v7 和 v8 中使用 =,仅不使用 #

以上是关于ARM 程序集中的立即数是不是需要散列?的主要内容,如果未能解决你的问题,请参考以下文章

ARM立即数判断

ARM指令集

YASM/NASM x86 程序集中立即数与方括号的基本使用

YASM/NASM x86 程序集中立即数与方括号的基本使用

ARM的伪指令

arm体系如何对SWI功能