我已经将一些汇编函数移植到64位ARM,并且它们在Android上可以正常工作,但是当我尝试在Xcode中编译相同的文件时,我发现clang使用了不同的语法(与ARM官方文档)。
[我已经找到了一些脚本将源文件从一种格式转换为另一种格式,但这不是理想的解决方案(并且当源文件包含预处理器定义时,这些脚本似乎不起作用。
我可以简单地在Xcode中使用gas还是将clang配置为接受gas语法?如果不是,那么clang汇编器文档在哪里?
UPDATE-2015年9月
似乎该问题已由XCode 7(新的clang版本?)解决了:现在,我可以导入为Android编写的程序集源文件,并且它们进行编译无需进行任何更改。
让我们以我的回答作为在Android和iOS上编写ARM64代码的一般指南。首先,我们将从volatile and non-volatile寄存器(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。文本对于每个功能,请添加这三行.section .text.MyFunctionName,“ ax”,%progbits.align 2.type MyFunctionName,%function
iOS(除align指令外,实际上不需要任何东西).align 2
声明公共(全局)标签
Android.global MyFunctionName
iOS.globl _MyFunctionName
下一个区别是获得指向源代码中定义的静态数据的指针。例如,假设您有一个数据表,并且希望使用指向该表的指针加载寄存器X0。
Android
adrp x0, MyDataTable
add x0, x0, #:lo12:MyDataTable
iOS
adrp x0,MyDataTable@PAGE
add x0,x0,MyDataTable@PAGEOFF
接下来,NEON语法。 iOS允许将大小信息附加到指令助记符,而Android要查看带有大小后缀的寄存器
Androidld1 {v0.16b},[x0],#16
iOSld1.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
仅此而已。如果有人发现有更多差异的特定案例,我将其添加。
您很幸运。 Libav团队支持一种接受gas语法并为Apple汇编程序输出汇编程序的工具。您可以在此处找到该工具:https://github.com/libav/gas-preprocessor/blob/master/gas-preprocessor.pl