我如何在iOS上开始使用ARM?

只是好奇如何开始了解iOS下的ARM。 任何帮助将是超级好。

在我看来,最好的入门方法是

  1. 编写C代码的小片段(后来的Objective-C)
  2. 看看相应的汇编代码
  3. 找出足够的了解汇编代码
  4. 重复!

要做到这一点,你可以使用Xcode:

  1. 创build一个新的iOS项目(一个单一的视图应用程序是好的)
  2. 添加一个C文件scratchpad.c
  3. 在“项目生成设置”中,将“生成debugging符号”设置为“否”
  4. 确保目标是iOS设备,而不是模拟器
  5. 打开scratchpad.c并打开助手编辑器
  6. 将助手编辑器设置为Assembly并select“Release”

例1

将下面的函数添加到scratchpad.c:

void do_nothing(void) { return; } 

如果您现在在助理编辑器中刷新大会,您应该看到许多以点(指令)开始的行,然后是

 _do_nothing: @ BB#0: bx lr 

现在让我们忽略指令,看看这三条线。 通过在互联网上search一下,你会发现这些线是:

  1. 标签(以下划线为前缀的函数的名称)。
  2. 只是编译器发出的一条评论。
  3. 返回声明。 b表示分支,现在忽略x (它与指令集之间的切换有关), lr是链接寄存器,其中调用者存储返回地址。

例2

让我们加强一下,并将代码更改为:

 extern void do_nothing(void); void do_nothing_twice(void) { do_nothing(); do_nothing(); } 

保存并刷新程序集后,您将获得以下代码:

 _do_nothing_twice: @ BB#0: push {r7, lr} mov r7, sp blx _do_nothing pop.w {r7, lr} bw _do_nothing 

再次,在网上search一下,你会发现每一行的含义。 需要做更多的工作,因为打两个电话:第一个电话需要返回给我们,所以我们需要改变lr 。 这是由blx指令完成的,它不仅分支到_do_nothing ,而且还将下一条指令(返回地址)的地址存储在lr

因为我们改变了返回地址,所以我们必须把它存储在某个地方,所以它被压入堆栈。 第二个跳转后缀为.w ,但现在让我们忽略它。 为什么不是这个function?

 _do_nothing_twice: @ BB#0: push {lr} blx _do_nothing pop.w {lr} bw _do_nothing 

这也可以,但在iOS中,约定是将帧指针存储在r7 。 帧指针指向堆栈中我们存储前一帧指针和前一个返回地址的地方。

因此,代码的作用是:首先,将r7lr推入堆栈,然后将r7设置为指向新的堆栈帧(位于堆栈顶部, sp指向堆栈顶部),然后它第一次分支,然后它恢复r7lr ,最后它第二次分支。 最后一个bx lr是不需要的,因为被调用的函数将返回到lr ,它指向我们的调用者。

例3

让我们来看看最后一个例子:

 void swap(int *x, int *y) { int temp = *x; *x = *y; *y = temp; } 

汇编代码是:

 _swap: @ BB#0: ldr r2, [r0] ldr r3, [r1] str r3, [r0] str r2, [r1] bx lr 

通过一些search,你会发现参数和返回值存储在寄存器r0r3 ,我们可以自由地使用它们来计算。 代码的作用很简单:它将r0r1指向的值加载到r2r3 ,然后将它们按交换顺序存储起来,然后分支回去。

等等

就是这样:编写小片段,获得足够的信息,粗略了解每一行中发生了什么,重复一遍。 希望有所帮助!