ARM64 using gas on iOS?

放肆的年华 提交于 2019-12-19 09:44:27

问题


I've got some assembly functions I've ported to 64-bit ARM, and they work fine on Android, but when I tried to compile the same files in Xcode, I discovered that clang uses a different syntax (different from the official ARM documentation).

I've found some scripts which convert a source file from one format to the other, but this is not the ideal solution (and it seems these scripts don't work when the source files contain preprocessor defines).

Can I simply use gas in Xcode, or configure clang to accept the gas syntax? If not, where is the clang assembler documentation?

UPDATE - September 2015

It seems that the issue is solved by XCode 7 (new clang version?): now I can import the assembly source files written for Android, and they are compiled without any change.


回答1:


Let's use my answer as a general guide to writing ARM64 code on Android and iOS. to begin, we'll start with the volatile and non-volatile registers (wikipedia):

X0-X7 - arguments and return value (volatile)
X8 = indirect result (struct) location (or temp reg)
X9-X15 = temporary (volatile)
X16-X17 - intro-call-use registers (PLT, Linker) or temp
X18 - platform specific use (TLS)
X19-X28 - callee saved registers (non-volatile)
X29 - frame pointer
X30 - link register (LR)
SP - stack pointer and zero (XZR)
V0-V7, V16-V31 - volatile NEON and FP registers
V8-V15 - callee saved registers (non-volatile, used for temp vars by compilers)

Next up is the assembler directives to correctly create the "segments" for your code:

Android
.cpu generic+fp+simd
.text
for each function, add these 3 lines
.section .text.MyFunctionName,"ax",%progbits
.align 2
.type MyFunctionName, %function

iOS (Nothing really needed except for the align directive)
.align 2

Declaring public (global) labels

Android
.global MyFunctionName

iOS
.globl _MyFunctionName <--notice the leading underscore and different spelling of the global directive

The next difference is in getting a pointer to static data defined in your source code. For instance, let's say you have a data table and you would like to load register X0 with a pointer to the table.

Android

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

iOS

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

Next, NEON syntax. iOS allows the size information to be appended to the instruction mnemonic while Android wants to see the register with the size suffix

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

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

Nested Loops
In 32-bit ARM code it was typical to push LR on the stack to preserve it for when you need to call a function from within a function. Since NEON instructions are no longer in a co-processor and have been merged into the main instruction set of Aarch64, there's no penalty for moving data back and forth. It's now practical to preserve X30 (LR) in an unused NEON register. For example:

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

That's all for now. If someone finds specific cases where there are more differences, I'll add them.




回答2:


You are in luck. The Libav team supports a tool that accepts gas syntax and outputs assembler for Apple's assembler. You can find the tool here: https://github.com/libav/gas-preprocessor/blob/master/gas-preprocessor.pl



来源:https://stackoverflow.com/questions/28109826/arm64-using-gas-on-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!