如何在XCode中使用ARM汇编程序?

只是为了教育目的,我想添加一个函数到现有的iPhone应用程序,用ARM程序集编写。 一般来说,我不需要关于ARM程序集的教程,因为我已经阅读了太多的教程。 我只是不知道如何实际运行代码!

我想要做的是这样的:

useless.h:

void useless(); 

useless.s:

 useless: bx lr 

如果这也可以在模拟器上工作,那就好了…在模拟器上.s文件不会编译,所以我也许应该这样做:

useless.s:

 #if I_AM_ARM useless: bx lr #endif 

useless.c:

 #if !I_AM_ARM void useless() { } #endif 

我知道我使用的语法已经坏了,但是我该如何正确写入? (因为我想尝试一些内联汇编,打破模拟器上的应用程序是不行的…)

次好的select是使用内联汇编,但是我更愿意使用非内联汇编。

谢谢!

编辑:我想学习ARM汇编,所以我想找一个方法来编译ARM汇编代码,并且汇编成EXECUTE的汇编代码。

我终于自己find了答案。 其实并不难。 我只解决了它的32位ARM版本。

useless.h:

 void useless(); 

useless.s:

 #ifdef __arm__ .syntax unified .globl _useless .align 2 .code 16 .thumb_func _useless _useless: //.cfi_startproc bx lr //.cfi_endproc // CFI means Call Frame Information // Optionally. Use for better debug-ability. #endif 

useless.c:

 #ifndef __arm__ void useless() { } #endif 

笔记:

CLANG ARM汇编程序的语法与您在整个Web上看到的示例有点不同。 注释以///* multiline comments */开头也支持。 它也理解标准的C预处理器。 该函数必须被定义为一个Thumb函数,如果你指定了一个arm函数( .code 32 ),程序就会崩溃。 行.thumb_func _useless可以被忽略,它仍然工作。 我不知道这意味着什么。 如果您省略.code 16行,程序崩溃。

关于#ifdef 。 对于ARMv7, __arm__被定义。 对于ARMv8,即iPhone 5S上的64位变体, __arm__没有定义,而是__arm64__被定义。 上面的代码不适用于64位ARM版本。 相反,将使用来自useless.c的实现。 (我没有忘记ARMv7s,目前我手上没有那个拱形的设备,所以我无法testing。)

模拟器不使用arm。 如果你想在模拟器上运行,你必须编写x86_64程序集。 (大概)。

我刚开始使用iOS。 我试图做的第一件事是添加asm代码到我的项目,并遇到了同样的问题。 在64位模式下,静态数据的处理方式稍有不同。 我发现如何通过查看编译器的汇编输出来实现。 相同的.S文件将在Xcode中被编译为32位和64位,所以准备如下:

  .globl _myfunction .align 2 my_constant_data: .byte 0,1,2,3,4,5,6,7 #ifdef __arm__ .thumb_func _myfunction .syntax unified .code 16 // // call from C as my myfunction() // _myfunction: ldr r0,=my_constant_data < write your thumb-2 code here > bx lr #else // or you can use #ifdef __arm64__ // // Call from C as myfunction() // _myfunction: adrp x0, my_constant_data@PAGE add x0,x0, my_constant_data@PAGEOFF < write your Armv8 code here > ret #endif 

学习的最好方法是看实际的工作示例,请参阅我的博客文章关于ARM iOS时序 。 这个Xcode项目的例子展示了如何混合一个函数的ARM ASM和C impls。 还有一个非常准确的计时模块来运行你的代码N次,因为准确的时间是优化代码的难点。

你可以用QEmu模拟ARM-Ubuntu(有一些Windows端口,例如http://lassauge.free.fr/qemu/ )。 如果您在Windows上,则可能需要在中间模拟x86_64-Ubuntu。 要创buildARM映像,您可以按照以下步骤操作: QEmu for ARM-Ubuntu中的黑屏(如何获取GUI?) (是的,不幸的是,这些步骤没有GUI,仅仅是ARM-Ubuntu的控制台机器,你必须从Ubuntu做的步骤)。 然后,可以将Windows / Ubuntu主机上的C ++ / C / Assembly程序交叉编译到ARM-Ubuntu目标。

 clang++.exe -Wall test1.cpp -o test1exe -std=c++14 -Ipath-to-arm-linaro/arm-linux-gnueabihf/include/c++/5.3.1 -Ipath-to-arm-linaro/arm-linux-gnueabihf/include/c++/5.3.1/arm-linux-gnueabihf -ffunction-sections -fdata-sections --sysroot=path-to-arm-linaro/arm-linux-gnueabihf/libc --target=arm-unknown-linux-gnueabihf -Bpath-to-arm-linaro/arm-linux-gnueabihf/bin/ 

对于交叉编译,您需要从https://releases.linaro.org下载并推出一个工具链,例&#x5982;gcc-linaro-5.3-2016.02-i686-mingw32_arm-linux-gnueabihf.tar.xz (Windows / MinGW) / components / toolchain / binaries / latest-5 / arm-linux-gnueabihf /并将上述命令中的“path-to-arm-linaro”replace为工具链的path。