在iOS上使用Gas的ARM64?

G B*_*G B 3 assembly android gnu-assembler ios arm64

我已经将一些汇编功能移植到了64位ARM,并且它们在Android上也能正常工作,但是当我尝试在Xcode中编译相同的文件时,我发现clang使用了不同的语法(与官方ARM不同)文档)。

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

我可以简单地在Xcode中使用gas还是将clang配置为接受gas语法?如果不是,那么clang汇编器文档在哪里?

更新-2015年9月

看来该问题已由XCode 7(新的clang版本?)解决了:现在,我可以导入为Android编写的程序集源文件,并且它们进行编译时无需进行任何更改。

Bit*_*ank 5

让我们用我的答案作为在Android和iOS上编写ARM64代码的一般指南。首先,我们将从易失性和非易失性寄存器(Wikipedia)开始:

X0-X7-参数和返回值(易失性)
X8 =间接结果(结构)位置(或临时注册表)
X9-X15 =临时(易失性)
X16-X17-呼叫使用寄存器(PLT,链接器)或临时
X18 -平台特定用途(TLS)
X19-X28-被调用方保存的寄存器(非易失性)
X29-帧指针 X30-
链接寄存器(LR)
SP-堆栈指针和零(XZR)
V0-V7,V16- V31- 易失性NEON和FP寄存器
V8-V15-被调用者保存的寄存器(非易失性,由编译器用于临时变量)

接下来是汇编程序指令,可为您的代码正确创建“段”:

每个功能的Android
.cpu通用+ fp + simd
.text
,将这3行添加到
.section .text.MyFunctionName,“ ax”,%progbits
.align 2
.type MyFunctionName,%function

iOS(除了align指令,实际上不需要任何东西)
.align 2

声明公共(全局)标签

Android
.global MyFunctionName

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

下一个区别是获得指向源代码中定义的静态数据的指针。例如,假设您有一个数据表,并且想用指向该表的指针加载寄存器X0。

安卓系统

  adrp  x0, MyDataTable
  add   x0, x0, #:lo12:MyDataTable
Run Code Online (Sandbox Code Playgroud)

的iOS

  adrp  x0,MyDataTable@PAGE
  add   x0,x0,MyDataTable@PAGEOFF
Run Code Online (Sandbox Code Playgroud)

接下来,NEON语法。iOS允许将大小信息附加到指令助记符,而Android要查看带有大小后缀的寄存器

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

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

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

  fmov d0,x30   // preserve LR
  <some code which makes function calls>
  fmov x30,d0   // restore LR
Run Code Online (Sandbox Code Playgroud)

目前为止就这样了。如果有人发现有更多差异的特定情况,我将其添加。