ARM64 在 iOS 上使用 gas?

ARM64 using gas on iOS?

我有一些汇编函数已移植到 64 位 ARM,它们在 Android 上运行良好,但是当我尝试在 Xcode 中编译相同的文件时,我发现 clang 使用不同的语法(与官方 ARM 文档不同)。

我找到了一些将源文件从一种格式转换为另一种格式的脚本,但这不是理想的解决方案(当源文件包含预处理器定义时,这些脚本似乎不起作用)。

我可以在 Xcode 中简单地使用 gas 或配置 clang 以接受 gas 语法吗?如果没有,clang 汇编程序文档在哪里?

更新 - 2015 年 9 月

看来XCode问题已经解决了 7(新的clang版本?):现在我可以导入为Android编写的汇编源文件,并且它们没有任何变化地被编译。

你很幸运。 Libav 团队支持一种工具,该工具接受 gas 语法并为 Apple 的汇编程序输出汇编程序。您可以在此处找到该工具:https://github.com/libav/gas-preprocessor/blob/master/gas-preprocessor.pl

让我们将我的回答作为在 Android 和 iOS 上编写 ARM64 代码的一般指南。首先,我们将从 volatile and non-volatile registers (wikipedia):

开始

X0-X7 - 参数和 return 值(易失性)
X8 = 间接结果(结构)位置(或临时寄存器)
X9-X15 = 临时(易失性)
X16-X17 - intro-call-use registers (PLT, Linker) or temp
X18 - 特定平台使用 (TLS)
X19-X28 - 被调用方保存的寄存器(非易失性)
X29 - 帧指针
X30 - link 寄存器 (LR)
SP - 堆栈指针和零 (XZR)
V0-V7、V16-V31 - 易失性 NEON 和 FP 寄存器
V8-V15 - 被调用方保存的寄存器(非易失性,编译器用于临时变量)

接下来是为您的代码正确创建 "segments" 的汇编程序指令:

Android
.cpu通用+fp+simd
.text
对于每个函数,添加这 3 行
.section .text.MyFunctionName,"ax",%progbits
.align 2
.type MyFunctionName, %function

iOS(除了 align 指令外,没有什么真正需要的)
.align 2

正在声明 public(全局)标签

Android
.global MyFunctionName

iOS
.globl _MyFunctionName <--注意全局指令的前导下划线和不同的拼写

下一个区别是获取指向源代码中定义的静态数据的指针。例如,假设你有一个数据 table 并且你想用指向 table.

的指针加载寄存器 X0

Android

  adrp  x0, MyDataTable
  add   x0, x0, #:lo12:MyDataTable

iOS

  adrp  x0,MyDataTable@PAGE
  add   x0,x0,MyDataTable@PAGEOFF

接下来,NEON 语法。 iOS 允许将大小信息附加到指令助记符,而 Android 想查看大小后缀为

的寄存器

Android
ld1 {v0.16b},[x0],#16

iOS
ld1.16b {v0},[x0],#16

嵌套循环
在 32 位 ARM 代码中,通常会将 LR 压入堆栈以在需要从函数内部调用函数时保留它。由于 NEON 指令不再位于协处理器中,并且已合并到 Aarch64 的主指令集中,因此来回移动数据不会受到任何惩罚。现在可以在未使用的 NEON 寄存器中保留 X30 (LR)。例如:

  fmov d0,x30   // preserve LR
  <some code which makes function calls>
  fmov x30,d0   // restore LR

暂时就这些。如果有人发现具体案例有更多不同,我会补充。