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

时间:2014-01-28 15:56:15

标签: ios xcode assembly 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

我知道我使用的语法已损坏,但如何正确编写? (仅仅因为我想尝试一些内联汇编而在模拟器上打破应用程序是没有选择的......)

第二个最好的选择是使用内联汇编,但我更倾向于非内联汇编。

谢谢!

编辑:我想学习ARM程序集,所以我想找到一个编译ARM汇编代码和EXECUTE ARM汇编代码的方法。

5 个答案:

答案 0 :(得分:2)

我终于找到了答案。实际上并不那么难。我只是为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,我现在手里还没有那个拱门的设备,所以我无法测试。)

答案 1 :(得分:1)

模拟器不使用手臂。如果你想让它在模拟器上运行,你必须编写x86_64程序集。 (可能)。

答案 2 :(得分:1)

最好的学习方法是查看实际工作示例,请参阅我的博客文章ARM iOS timing。此示例Xcode项目显示了如何混合ARM ASM和函数的C impls。还有一个非常精确的计时模块可以运行你的代码N次,因为在优化代码时,准确的计时是最困难的部分。

答案 3 :(得分:0)

我刚开始使用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

答案 4 :(得分:0)

You can emulate ARM-Ubuntu with QEmu (there are some Windows ports of it, e.g. http://lassauge.free.fr/qemu/ ). If you are on Windows, you may need to emulate x86_64-Ubuntu in the middle. To create an ARM image you can follow the steps from this question: Black screen in QEmu for ARM-Ubuntu (how to get GUI?) (yes, unfortunately, you get no GUI with these steps, just a console to the ARM-Ubuntu machine, and you have to do the steps from Ubuntu). Then you can cross-compile your C++/C/Assembly programs from Windows/Ubuntu host to ARM-Ubuntu target.

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/

For cross-compilation you would need to download and roll out a toolchain, e.g. gcc-linaro-5.3-2016.02-i686-mingw32_arm-linux-gnueabihf.tar.xz (Windows/MinGW) from https://releases.linaro.org/components/toolchain/binaries/latest-5/arm-linux-gnueabihf/ and replace "path-to-arm-linaro" in the above command with the path to the toolchain.