如何开始在 iOS 上使用 ARM? [英] How do I get started with ARM on iOS?

查看:21
本文介绍了如何开始在 iOS 上使用 ARM?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是好奇如何开始了解iOS下的ARM.任何帮助都会非常好.

Just curious as to how to get started understanding ARM under iOS. Any help would be super nice.

推荐答案

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

In my opinion, the best way to get started is to

  1. 编写一小段 C 代码(后来的 Objective-C)
  2. 查看对应的汇编代码
  3. 找出足以理解汇编代码的内容
  4. 重复!

为此,您可以使用 Xcode:

To do this you can use Xcode:

  1. 创建一个新的 iOS 项目(单视图应用程序就可以了)
  2. 添加一个 C 文件scratchpad.c
  3. 在项目构建设置中,将生成调试符号"设置为否"
  4. 确保目标是 iOS 设备,而不是模拟器
  5. 打开scratchpad.c并打开助理编辑器
  6. 将助理编辑器设置为Assembly并选择Release"

示例 1

在scratchpad.c中添加如下函数:

Example 1

Add the following function to scratchpad.c:

void do_nothing(void)
{
    return;
}

如果您现在在辅助编辑器中刷新程序集,您应该看到许多以点(指令)开头的行,然后是

If you now refresh the Assembly in the assistant editor, you should see lots of lines starting with dots (directives), followed by

_do_nothing:
@ BB#0:
    bx  lr

让我们暂时忽略这些指令,看看这三行.通过在互联网上进行一些搜索,您会发现这些行是:

Let's ignore the directives for now and look at these three lines. With a bit of searching on the internet, you'll find out that these lines are:

  1. 标签(带有下划线前缀的函数名称).
  2. 只是编译器发出的注释.
  3. 返回语句.b 表示分支,暂时忽略x(与指令集切换有关),lr 是链接寄存器, 调用者存储返回地址的位置.
  1. A label (the name of the function prefixed with an underscore).
  2. Just a comment emitted by the compiler.
  3. The return statement. The b means branch, ignore the x for now (it has something to do with switching between instruction sets), and lr is the link register, where callers store the return address.

示例 2

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

Example 2

Let's beef it up a bit and change the code to:

extern void do_nothing(void);

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

保存并刷新程序集后,得到如下代码:

After saving and refreshing the assembly, you get the following code:

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

再一次,通过在互联网上进行一些搜索,您会发现每一行的含义.还有一些工作需要做,因为要进行两次调用: 第一次调用需要返回给我们,因此我们需要更改lr.这是由blx指令完成的,它不仅跳转到_do_nothing,还在lr<中存储了下一条指令的地址(返回地址)/代码>.

Again, with a bit of searching on the internet, you'll find out the meaning of each line. Some more work needs to be done because make two calls: The first call needs to return to us, so we need to change lr. That is done by the blx instruction, which does not only branch to _do_nothing, but also stores the address of the next instruction (the return address) in lr.

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

Because we change the return address, we have to store it somewhere, so it is pushed on the stack. The second jump has a .w suffixed to it, but let's ignore that for now. Why doesn't the function look like this?

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

这也可以,但在 iOS 中,约定是将帧指针存储在 r7 中.帧指针指向栈中我们存放前一帧指针和前一返回地址的位置.

That would work as well, but in iOS, the convention is to store the frame pointer in r7. The frame pointer points to the place in the stack where we store the previous frame pointer and the previous return address.

那么代码的作用是:首先,它将r7lr压入堆栈,然后将r7设置为指向新的栈帧(在栈顶,sp指向栈顶),然后第一次分支,然后恢复r7lr,最后它第二次分支.不需要末尾的bx lr,因为被调用的函数会返回lr,它指向我们的调用者.

So what the code does is: First, it pushes r7 and lr to the stack, then it sets r7 to point to the new stack frame (which is on the top of the stack, and sp points to the top of the stack), then it branches for the first time, then it restores r7 and lr, finally it branch for the second time. Abx lr at the end is not needed, because the called function will return to lr, which points to our caller.

让我们看最后一个例子:

Let's have a look at a last example:

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

通过一些搜索,您将了解到参数和返回值存储在寄存器 r0-r3 中,我们可以自由地使用它们进行计算.代码的作用很简单:它加载 r0r1r2r3 中指向的值,然后它以交换的顺序将它们存储回来,然后分支回来.

With a bit of searching, you will learn that arguments and return values are stored in registers r0-r3, and that we may use those freely for our calculations. What the code does is straightforward: It loads the value that r0 and r1 point to in r2 and r3, then it stores them back in exchanged order, then it branches back.

就是这样:编写小片段,获取足够的信息以大致了解每一行中发生的事情,重复.希望有帮助!

That's it: Write small snippets, get enough info to roughly understand what's going on in each line, repeat. Hope that helps!

这篇关于如何开始在 iOS 上使用 ARM?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆