一直在想 iOS 匯編是怎么樣的,變量是怎么保存的?如何調(diào)函數(shù)的?如何判斷條件的?昨天看了一天的匯編,也不是很懂,特別是adrp 指令有點(diǎn)難懂,碰到自己不會的東西,我自己是多去分析已知的匯編,將自己的匯編多看唄,看多自然就懂了。
阿里大牛知兵的知乎專欄
ARM64 匯編——寄存器和指令
iOS開發(fā)同學(xué)的arm64匯編入門
10分鐘入門arm64匯編
ARM64 匯編——寄存器和指令
一般局部變量會存放在棧中,
OC 代碼
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
int a = 10;
int b = 20;
int c = a + b;
NSLog(@"%d",c);
}
其中int a = 10; int b = 20; int c = a + b;對應(yīng)匯編如下。局部變量存放在棧,然后再取,最后加法操作
0x10236e740 <+68>: mov w11, #0x14;將14存放在w11位
0x10236e744 <+72>: mov w12, #0xa;將10存放在w12位
-> 0x10236e748 <+76>: str w12, [sp, #0x1c];將w12存放在sp +28位,w只占用4位
0x10236e74c <+80>: str w11, [sp, #0x18];將w11存放在sp +24位
0x10236e750 <+84>: ldr w11, [sp, #0x1c];加載sp +28給w11
0x10236e754 <+88>: ldr w12, [sp, #0x18];加載sp +24位給w12
0x10236e758 <+92>: add w11, w11, w12;將w11 + w12 賦值給w11
轉(zhuǎn)成匯編語言
-[ViewController viewDidLoad]:
0x10236e6fc <+0>: sub sp, sp, #0x50 ; =0x50 將 sp 向下移動 16 x 5 = 80個字節(jié),
0x10236e700 <+4>: stp x29, x30, [sp, #0x40]; 將x29 = fp,x30 =lr ,lr 是下條返回地址,放在sp 向上移動64個的位置,x29 和 x30 各占用了8個字節(jié)
0x10236e704 <+8>: add x29, sp, #0x40 ; fp 指向其賦值的位置
0x10236e708 <+12>: add x8, sp, #0x20; 將sp+16數(shù)據(jù)存放在x8中
0x10236e70c <+16>: adrp x9, 2 ;將 pc 的地址取到,pc = 0x00000001029d2798, x9 = 0x00000001029d4000
0x10236e710 <+20>: add x9, x9, #0xca8; =0xca8 取方法的地址
0x10236e714 <+24>: adrp x10, 2 ;
0x10236e718 <+28>: add x10, x10, #0xcc8 ; =0xcc8 取方法地址
0x10236e71c <+32>: stur x0, [x29, #-0x8];將x0 的數(shù)據(jù)放在fp - 8的位置
0x10236e720 <+36>: stur x1, [x29, #-0x10];將x1 的數(shù)據(jù)放在fp - 16的位置
0x10236e724 <+40>: ldur x0, [x29, #-0x8];將fp - 8的數(shù)賦值給x0
0x10236e728 <+44>: str x0, [sp, #0x20];將x0 存放在 sp + 32地址中
0x10236e72c <+48>: ldr x10, [x10];將x10 存放地址所指向的數(shù)據(jù)賦值給 x10
0x10236e730 <+52>: str x10, [sp, #0x28];將x10數(shù)據(jù)存放在sp + 24
0x10236e734 <+56>: ldr x1, [x9];將x1 的數(shù)據(jù)賦值給x9存方地址所指的空間。
0x10236e738 <+60>: mov x0, x8;將x8 賦值給 x0
0x10236e73c <+64>: bl 0x10236eb84 ; symbol stub for: objc_msgSendSuper2; 調(diào)用父類方法
0x10236e740 <+68>: mov w11, #0x14;將14存放在w11位
0x10236e744 <+72>: mov w12, #0xa;將10存放在w12位
-> 0x10236e748 <+76>: str w12, [sp, #0x1c];將w12存放在sp +28位,w只占用4位
0x10236e74c <+80>: str w11, [sp, #0x18];將w11存放在sp +24位
0x10236e750 <+84>: ldr w11, [sp, #0x1c];加載sp +28給w11
0x10236e754 <+88>: ldr w12, [sp, #0x18];加載sp +24位給w12
0x10236e758 <+92>: add w11, w11, w12;將w11 + w12 賦值給w11
0x10236e75c <+96>: str w11, [sp, #0x14];將w11值給sp+20
0x10236e760 <+100>: ldr w11, [sp, #0x14];加載sp+20給w11
0x10236e764 <+104>: mov x0, x11;將x11的值給x0
0x10236e768 <+108>: mov x8, sp
0x10236e76c <+112>: str x0, [x8]
0x10236e770 <+116>: adrp x0, 2
0x10236e774 <+120>: add x0, x0, #0x60 ; =0x60 ;
0x10236e778 <+124>: bl 0x10236eb3c ; symbol stub for: NSLog
0x10236e77c <+128>: ldp x29, x30, [sp, #0x40];將sp + 64 位置將賦值給x29,x 30
0x10236e780 <+132>: add sp, sp, #0x50 ; =0x50 ;恢復(fù)sp平衡
0x10236e784 <+136>: ret
adrp, 用來定位數(shù)據(jù)段中的數(shù)據(jù)用, 因?yàn)閍slr會導(dǎo)致代碼及數(shù)據(jù)的地址隨機(jī)化, 用adrp來根據(jù)pc做輔助定位(本人對adrp理解不夠深入,里面不太懂);
sp 和 bp 之間空間是存放函數(shù)的變量。
x/s 打印寄存中的內(nèi)容
po $x0
po (char*)$x0
(lldb) x/s $x1
0x18da1bbb3: "viewDidLoad"
(lldb) x/s $x0
0x113e0bd00: "\xffffffddL\xffffffa2"
(lldb) x/s $x2