[英]How do I get started with ARM on iOS?
只是好奇如何開始了解iOS下的ARM。 任何幫助都會非常好。
在我看來,最好的入門方式是
為此,您可以使用Xcode:
將以下函數添加到scratchpad.c:
void do_nothing(void)
{
return;
}
如果您現在在助理編輯器中刷新程序集,您應該看到許多以點(指令)開頭的行,然后是
_do_nothing:
@ BB#0:
bx lr
我們暫時忽略這些指令並查看這三行。 通過在互聯網上進行一些搜索,您會發現這些行是:
b
表示分支,暫時忽略x
(它與指令集之間的切換有關), lr
是鏈接寄存器,其中調用者存儲返回地址。 讓我們加強一點並將代碼更改為:
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}
b.w _do_nothing
再次,通過在互聯網上進行一些搜索,您將找到每一行的含義。 還有一些工作要做,因為要進行兩次調用:第一次調用需要返回給我們,所以我們需要更改lr
。 這是由blx
指令完成的,它不僅分支到_do_nothing
,而且還存儲lr
下一條指令(返回地址)的地址。
因為我們更改了返回地址,所以我們必須將它存儲在某個地方,因此它會被壓入堆棧。 第二個跳轉后綴為.w
,但現在讓我們忽略它。 為什么函數看起來不像這樣?
_do_nothing_twice:
@ BB#0:
push {lr}
blx _do_nothing
pop.w {lr}
b.w _do_nothing
這也可以,但在iOS中,慣例是將幀指針存儲在r7
。 幀指針指向堆棧中我們存儲前一幀指針和前一個返回地址的位置。
所以代碼的作用是:首先,它將r7
和lr
推送到堆棧,然后將r7
設置為指向新的堆棧幀(位於堆棧的頂部, sp
指向堆棧的頂部),然后它第一次分支,然后它恢復r7
和lr
,最后它分支第二次。 最后不需要bx lr
,因為被調用的函數將返回lr
,它指向我們的調用者。
我們來看看最后一個例子:
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
,並且我們可以自由地使用它們進行計算。 代碼所做的很簡單:它加載r0
和r1
指向r2
和r3
,然后將它們以交換順序存儲回來,然后分支回來。
就是這樣:編寫小片段,獲取足夠的信息以粗略地了解每行中發生的事情,重復一遍。 希望有所幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.