如何在 iPhone 上进行内联汇编?

发布于 2024-07-07 17:40:54 字数 40 浏览 8 评论 0原文

它是如何完成的? 我需要采取哪些步骤以及需要考虑哪些陷阱和问题?

How is it done? What steps do I need to take and what pitfalls and gotchas are there to consider?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

自控 2024-07-14 17:40:54

我已经让它工作了,感谢 Apple Devforums 上的一些内部帮助,您应该注册,如果您是一名专注的 iPhone 开发人员。

首先,它是__asm__(),而不是普通的asm()

其次,默认情况下,XCode 生成一个编译目标,该目标根据 ARM Thumb 指令集编译内联汇编,因此 usat 未被识别为正确的指令。 要解决此问题,请在目标上执行“获取信息”。 向下滚动到“GCC 4.0 - 代码生成”部分,然后取消选中“Compile for Thumb”。 如果您将 Active SDK 设置为“Device”,那么下面的代码片段将可以正常编译,

inline int asm_saturate_to_255 (int a) {
  int y;
  __asm__("usat %0, #8, %1\n\t" : "=r"(y) : "r"(a));
  return y;
}

当然,现在它无法与 iPhone 模拟器一起使用。 但是 TargetConditionals.h 已经定义了您可以 #ifdef 反对的定义。 即TARGET_OS_IPHONETARGET_IPHONE_SIMULATOR

I've gotten this to work, thanks to some inside help over at the Apple Devforums, you should sign up if you're a dedicated IPhone developer.

First thing's first, it's __asm__(), not plain asm().

Secondly, by default, XCode generates a compilation target that compiles inline assembly against the ARM Thumb instruction set, so usat wasn't recognized as a proper instruction. To fix this, do "Get Info" on the Target. Scroll down to the section "GCC 4.0 - Code Generation" and uncheck "Compile for Thumb". Then this following snippet will compile just fine if you set the Active SDK to "Device"

inline int asm_saturate_to_255 (int a) {
  int y;
  __asm__("usat %0, #8, %1\n\t" : "=r"(y) : "r"(a));
  return y;
}

Naturally, now it won't work with the IPhone Simulator. But TargetConditionals.h has defines you can #ifdef against. Namely TARGET_OS_IPHONE and TARGET_IPHONE_SIMULATOR.

哎呦我呸! 2024-07-14 17:40:54

我编写了大量 ARM Cortex-A8 汇编代码。 iPhone 上的 CPU 是 ARM11(据我所知),因此核心指令集是相同的。

您到底在寻找什么? 如果你愿意的话我可以给你一些例子。


编辑:

我刚刚发现在 iPhone 上你必须使用 llvm-gcc 编译器。 据我所知它应该理解 GCC 的内联汇编语法。 如果是这样,所有 ARM 内联汇编器教程也将在 iPhone 上运行。

这是一个非常小的内联汇编函数(C 语言)。 你能告诉我它是否可以在 iphone 上编译并运行吗? 如果它有效,我可以咆哮一下如何在 ARM 内联汇编器中做有用的事情,特别是对于 ARMv6 架构和 DSP 扩展。

inline int saturate_to_255 (int a)
{
  int y;
  asm ("usat %0, #8, %1\n\t" : "=r"(y) : "r"(a));
  return y;
}

应等于:

inline int saturate_to_255 (int a)
{
  if (a < 0) a =0;
  if (a > 255) a = 255;
  return a;
}

I write quite a bit of ARM Cortex-A8 assembly-code. The CPU on the iPhone is an ARM11 (afaik) so the core instruction set is the same.

What exactly are you looking for? I could give you some examples if you want.


EDIT:

I just found out that on the iPhone you have to use the llvm-gcc compiler. As far as I know it should understand the inline assembler syntax from GCC. If so all the ARM inline assembler tutorials will work on the iPhone as well.

Here is a very minimal inline assembler function (in C). Could you please tell me if it compiles and works on the iphone? If it works I can rant a bit how to do usefull stuff in ARM inline assembler, especially for the ARMv6 architecture and the DSP extensions.

inline int saturate_to_255 (int a)
{
  int y;
  asm ("usat %0, #8, %1\n\t" : "=r"(y) : "r"(a));
  return y;
}

should be equivalent to:

inline int saturate_to_255 (int a)
{
  if (a < 0) a =0;
  if (a > 255) a = 255;
  return a;
}
野却迷人 2024-07-14 17:40:54

寄存器也可以在内联汇编中显式使用

void foo(void) {
#if TARGET_CPU_ARM64
    __asm ("sub        sp, sp, #0x60");
    __asm ("str        x29, [sp, #0x50]");
#endif
}

The registers can also be used explicitly in inline asm

void foo(void) {
#if TARGET_CPU_ARM64
    __asm ("sub        sp, sp, #0x60");
    __asm ("str        x29, [sp, #0x50]");
#endif
}
空气里的味道 2024-07-14 17:40:54

对于不需要重度浮动操作的应用,建议使用拇指。 Thumb 使代码尺寸更小,并且代码执行速度更快。

所以你应该只在 3D 游戏等应用程序中关闭 Thumb...

Thumb is recommended for application which do not require heavy float operation. Thumb makes the code size smaller and results also in a faster code execution.

So you should only turn Thumb off for application like 3D games...

能否归途做我良人 2024-07-14 17:40:54

背景

  • 现在是2021年-> 其他答案似乎太旧了?
  • 大多数 iOS 设备(iPhone 等)是 ARM 64 位: arm64

iPhone 上的内联汇编

asm 关键字

  • GNU/GCC 编译器
    • 标准 C(编译标志:-ansi / -std):使用 __asm__
    • GNU 扩展:使用 asm
  • ARM 编译器: 使用 __asm

asm 语法

AFAIK,有很多 asm 语法

  • asm 语法
    • AT&T 语法 ~= GNU 语法 ~= UNIX 语法
    • 英特尔语法
    • ARM 语法

这里只关注最常用的 GNU/GCC 语法

GNU/UNIX 语法

Basic Asm

asm("assembly code");
__asm__("assembly code");

Extended Asm

asm asm-qualifiers ( AssemblerTemplate 
                 : OutputOperands 
                 [ : InputOperands
                 [ : Clobbers ] ])

My Examples 代码

  • 环境
    • 开发者
      • macOS
        • IDE:XCode
          • 编译器:clang
    • 跑步
      • iOS - iPhone
        • 硬件架构:ARM64

调用ARM64的svc 0x80

  • 内联asm使用扩展Asm内联asm
// inline asm code inside iOS ObjC code
__attribute__((always_inline)) long svc_0x80_syscall(int syscall_number, const char * pathname, struct stat * stat_info) {
    register const char * x0_pathname asm ("x0") = pathname; // first arg
    register struct stat * x1_stat_info asm ("x1") = stat_info;  // second arg
    register int x16_syscall_number asm ("x16") = syscall_number; // special syscall number store to x16

    register int x4_ret asm("x4") = -1; // store result

    __asm__ volatile(
         "svc #0x80\n"
         "mov x4, x0\n"
        : "=r"(x4_ret)
        : "r"(x0_pathname), "r"(x1_stat_info), "r"(x16_syscall_number)
//         : "x0", "x1", "x4", "x16"
    );
    return x4_ret;
}
  • ObjC代码调用内联asm
// normal ObjC code
#import <sys/syscall.h>

...
    int openResult = -1;
    struct stat stat_info;
    const char * filePathStr = [filePath UTF8String];
...
  // call inline asm function
    openResult = svc_0x80_syscall(SYS_stat64, filePathStr, &stat_info);

文档

Background

  • Now is 2021 year -> other answer seems is too old?
  • the most iOS device(iPhone etc.) is ARM 64bit: arm64

Inline assembly on the iPhone

asm keyword

  • GNU/GCC compiler
    • standard C (compile flag: -ansi / -std): use __asm__
    • GNU extensio: use asm
  • ARM compiler: use __asm

asm syntax

AFAIK, there many asm syntax

  • asm syntax
    • AT&T syntax ~= GNU syntax ~= UNIX syntax
    • Intel syntax
    • ARM syntax

here only focus on most common used GNU/GCC syntax

GNU/UNIX syntax

Basic Asm

asm("assembly code");
__asm__("assembly code");

Extended Asm

asm asm-qualifiers ( AssemblerTemplate 
                 : OutputOperands 
                 [ : InputOperands
                 [ : Clobbers ] ])

My Example code

  • environment
    • dev
      • macOS
        • IDE: XCode
          • compiler: clang
    • running
      • iOS - iPhone
        • hardware arch: ARM64

inline asm to call svc 0x80 for ARM64 using Extended Asm

  • inline asm inside ObjC code
// inline asm code inside iOS ObjC code
__attribute__((always_inline)) long svc_0x80_syscall(int syscall_number, const char * pathname, struct stat * stat_info) {
    register const char * x0_pathname asm ("x0") = pathname; // first arg
    register struct stat * x1_stat_info asm ("x1") = stat_info;  // second arg
    register int x16_syscall_number asm ("x16") = syscall_number; // special syscall number store to x16

    register int x4_ret asm("x4") = -1; // store result

    __asm__ volatile(
         "svc #0x80\n"
         "mov x4, x0\n"
        : "=r"(x4_ret)
        : "r"(x0_pathname), "r"(x1_stat_info), "r"(x16_syscall_number)
//         : "x0", "x1", "x4", "x16"
    );
    return x4_ret;
}
  • call inline asm
// normal ObjC code
#import <sys/syscall.h>

...
    int openResult = -1;
    struct stat stat_info;
    const char * filePathStr = [filePath UTF8String];
...
  // call inline asm function
    openResult = svc_0x80_syscall(SYS_stat64, filePathStr, &stat_info);

Doc

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文