寄存器 :
ARM64中? ??64位: X0-X30, XZR(零寄存器)? ?32位: W0-W30, WZR(零寄存器)
PC 寄存器, 如果需要改變PC 寄存器,需要用到 bl 跳轉(zhuǎn)指令
??臻g是通過操作sp寄存器開辟的空間
SP和FP寄存器
sp寄存器在任意時刻會保存我們棧頂?shù)牡刂? sp往高地址走都是棧區(qū)域,sp往低地址走是沒用的。


fp寄存器也稱為x29寄存器屬于通用寄存器,但是在某些時刻我們利用它保存棧底的地址!
注意:ARM64開始,取消32位的 LDM,STM,PUSH,POP指令! 取而代之的是ldr\ldp str\stp
ARM64里面 對棧的操作是16字節(jié)對齊的!!
在arm64 中不存在 push pop操作,如果往棧區(qū)域讀寫信息,用的是 str (從寄存器寫入到內(nèi)存)、ldr (從內(nèi)存中讀取到寄存器中)
進(jìn)入函數(shù)會開辟??臻g,函數(shù)調(diào)用完畢,會將棧中的數(shù)據(jù)釋放,叫做棧平衡。(函數(shù)調(diào)用之前和之后,棧的sp 寄存器指向的位置是不變的,開辟的時候 sp -,釋放的時候 sp + )
bl和ret指令
bl標(biāo)號(跳轉(zhuǎn),跳到指定的函數(shù)地址)
將下一條指令的地址放入lr(x30)寄存器
轉(zhuǎn)到標(biāo)號處執(zhí)行指令
ret(返回回去)
默認(rèn)使用lr(x30)寄存器的值,通過底層指令提示CPU此處作為下條指令地址!
ARM64平臺的特色指令,它面向硬件做了優(yōu)化處理的
x30寄存器(回去的路)
x30寄存器存放的是函數(shù)的返回地址.當(dāng)ret指令執(zhí)行時刻,會尋找x30寄存器保存的地址值!
注意:在函數(shù)嵌套調(diào)用的時候.需要講x30入棧!


這種寫法會造成最終無法回到main 函數(shù)中,在 A函數(shù)中一直死循環(huán),因?yàn)?main 到A中x30寄存器保存了回家的路,但是A到B是,x30保存了A的bl下一條指令的地址,所以在B ret后會一直在A中死循環(huán)。

?0x10120a948<+0>:? stp? ? x29, x30, [sp,#-0x10]!? ?(相當(dāng)于 x -= x)
stp 也是一種寫入的指令。將 x29 x30 放到 sp 減去 16個字節(jié)的位置,并且將sp 減去 0x10,
?? 0x10120a954<+12>: ldp? ? x29, x30, [sp],#0x10
將當(dāng)前的值取出來賦值給x29 x30 ,然后 把sp 的值加上 0x10,
這種指令只能在??臻g只需要保護(hù) x29 x30,只有簡單的調(diào)用,局部變量也么有。

ldr : r? 取出來16個字節(jié), ldp : p 取出來 32個字節(jié)
[sp] 的意思是,把sp作為一個內(nèi)存地址,取出該內(nèi)存地址中的值。
str x30,[sp,#-0x10]!? ?意思是, 以?sp,#-0x10 為尋址,把x30的值放到 [sp,#-0x10] 內(nèi)存地址中,x寄存器是8個字節(jié)
ARM64對棧的操作是 16個字節(jié)對齊的,所以挪動 sp 一定是16的倍數(shù)。

w8是x8寄存器的低32位,把x8的值給了x0,? w 寄存器就是 x 寄存器的低 地址的寄存器,高地址的全為0, 節(jié)約內(nèi)存是在寫入到棧區(qū)的時候節(jié)約的
64位: X0-X30, XZR(零寄存器)
32位: W0-W30, WZR(零寄存器)

函數(shù)的參數(shù)和返回值
ARM64下,函數(shù)的參數(shù)是存放在X0到X7(W0到W7)這8個寄存器里面的.如果超過8個參數(shù),就會入棧.
函數(shù)的返回值?是放在X0 寄存器里面的.




當(dāng)我們的??臻g給別人用的時候,給接下來的函數(shù)調(diào)用棧使用時,棧區(qū)域從棧頂 sp 開始存放數(shù)據(jù),如果存放自己的數(shù)據(jù),從棧底 x29 開始的。
超過了8個參數(shù),需要用到棧,通過寄存器的訪問最高效。