一、bl指令


bl:即調函數。調用完函數后返回原代碼,繼續(xù)玩下執(zhí)行。
相當于在代碼中調用一個函數,函數調用完后繼續(xù)往下執(zhí)行原代碼。
1、匯編代碼bl

匯編代碼bl

斷點到bl mycode

進入到mycode

返回到test函數
2、OC代碼中看匯編bl

OC源代碼斷點

匯編斷點處

開始bl跳轉

進入mytest函數

從mytest函數出來,繼續(xù)往下執(zhí)行
二、ldr指令
ld:load,即讀取的意思
ldr:取內存中的數據,放到另一個寄存器中。
涉及到內存尋址的問題。
1、內存尋址


image.png
2、代碼

OC代碼--斷點

匯編代碼--斷點

匯編調試ldr:1、先得到一個能訪問的地址&a,不能瞎訪問
三、ldur指令
ldur與ldr的區(qū)別:
ldr用于正數(偏移值是正數);
ldur用于負數(偏移值是負數)。

四、ldp指令
ldp:load pair ,一對寄存器
根據地址讀取一對數據,按地址順序賦值給一對寄存器:
1、先賦值給第一個寄存器;
2、偏移地址后,取值賦值給第二個寄存器。

獲取&a得到一個有用的地址

五、str、stur、stp指令
st:store,存儲。
str:往內存中寫數據(偏移值為正)

OC

匯編

調試
stur:往內存中寫數據(偏移值為負)

image.png
stp:
p:pair
stp:store pair,存放一對數據
一對數據,從右邊那個地址開始按順序存放。
格式:寄存器寫在左邊,內存尋址寫右邊。

五、wzr、xzr寄存器
wzr:4字節(jié),不能在lldb中讀,也不能在lldb中寫
xzr:8字節(jié),不能在lldb中讀,也不能在lldb中寫

lldb讀不出來:

但是在代碼里是能寫的:


為什么要有0寄存器呢?
——因為,如果我們要把某塊內存置零的話,是不能這么寫立即數的:
str #0x0, [x1]
雖然可以這么寫:

但清零這種操作很常見,false,NO,nil等都是清零操作,所以專門設計出存儲0的寄存器
六、pc、lr寄存器

概念
1、pc寄存器

查看pc寄存器

查看lr寄存器
2、演示lr寄存器

image.png

image.png

image.png

image.png
七、bl指令的本質
b指令的事情就一件,找到標記,跳轉,開始執(zhí)行代碼。
bl指令:跳轉,返回。(bl跟ret配合使用)
lr:在bl跳轉之前,會將下一行代碼的地址賦值給lr寄存器。
ret的本質:函數返回——將lr(x30)寄存器的值賦給pc寄存器。
八、函數的分類

葉子函數:里面沒有別的函數了;
非葉子函數:里面還有別的函數。
把oc文件轉成匯編,亂七八糟的東西太多了,把c文件轉成匯編,比較純凈。
c文件轉成匯編指令:
xcrun --sdk iphoneos clang -S -arch arm64 main.c -o main.s