Radare2靜態(tài)分析ARM64-Android

在使用Radare2靜態(tài)分析apk(2)末尾通過(guò)Radare2分析出一段ARM64匯編代碼,這篇文通過(guò)分析這段匯編代碼來(lái)來(lái)了解下ARM64匯編。
完整的代碼
? ? ? ? ? ?; UNKNOWN XREF from unk @
┌ 156: sym.Java_com_example_myapplication_MainActivity_stringFromJNI (int64_t arg1, int64_t arg2);
│ ? ? ? ? ? ; var int64_t var_28h @ x29-0x28
│ ? ? ? ? ? ; var int64_t var_bp_8h @ x29-0x8
│ ? ? ? ? ? ; var int64_t var_0h @ sp+0x0
│ ? ? ? ? ? ; var int64_t var_8h @ sp+0x8
│ ? ? ? ? ? ; var int64_t var_10h @ sp+0x10
│ ? ? ? ? ? ; var char *var_18h @ sp+0x18
│ ? ? ? ? ? ; var int64_t var_0h_2 @ sp+0x30
│ ? ? ? ? ? ; var int64_t var_20h @ sp+0x40
│ ? ? ? ? ? ; var int64_t var_60h @ sp+0x60
│ ? ? ? ? ? ; var int64_t var_60h_2 @ sp+0x68
│ ? ? ? ? ? ; arg int64_t arg1 @ x0
│ ? ? ? ? ? ; arg int64_t arg2 @ x1
│ ? ? ? ? ? 0x0000f08c ? ? ?ffc301d1 ? ? ? sub sp, sp, 0x70
│ ? ? ? ? ? 0x0000f090 ? ? ?fd7b06a9 ? ? ? stp x29, x30, [var_60h]
│ ? ? ? ? ? 0x0000f094 ? ? ?fd830191 ? ? ? add x29, var_60h
│ ? ? ? ? ? 0x0000f098 ? ? ?48d03bd5 ? ? ? mrs x8, tpidr_el0
│ ? ? ? ? ? 0x0000f09c ? ? ?081540f9 ? ? ? ldr x8, [x8, 0x28] ? ? ? ? ?; aav.0x00000028
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; [0x28:4]=0x341f8
│ ? ? ? ? ? 0x0000f0a0 ? ? ?a8831ff8 ? ? ? stur x8, [var_bp_8h]
│ ? ? ? ? ? 0x0000f0a4 ? ? ?a0831df8 ? ? ? stur x0, [var_28h] ? ? ? ? ?; arg1
│ ? ? ? ? ? 0x0000f0a8 ? ? ?e11b00f9 ? ? ? str x1, [var_0h_2] ? ? ? ? ?; arg2
│ ? ? ? ? ? 0x0000f0ac ? ? ?c10000b0 ? ? ? adrp x1, 0x28000
│ ? ? ? ? ? 0x0000f0b0 ? ? ?21201191 ? ? ? add x1, x1, 0x448 ? ? ? ? ? ; 0x28448 ; "Hello from C++" ; section..rodata
│ ? ? ? ? ? 0x0000f0b4 ? ? ?a88300d1 ? ? ? sub x8, var_20h
│ ? ? ? ? ? 0x0000f0b8 ? ? ?e00308aa ? ? ? mov x0, x8
│ ? ? ? ? ? 0x0000f0bc ? ? ?e80f00f9 ? ? ? str x8, [var_18h]
│ ? ? ? ? ? 0x0000f0c0 ? ? ?94ffff97 ? ? ? bl fcn.0000ef10
│ ? ? ? ? ? 0x0000f0c4 ? ? ?a0835df8 ? ? ? ldur x0, [var_28h]
│ ? ? ? ? ? 0x0000f0c8 ? ? ?e80f40f9 ? ? ? ldr x8, [var_18h] ? ? ? ? ? ; aav.0x00000018
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; [0x18:4]=0xf050 pc ; "P\xf0"
│ ? ? ? ? ? 0x0000f0cc ? ? ?e00b00f9 ? ? ? str x0, [var_10h]
│ ? ? ? ? ? 0x0000f0d0 ? ? ?e00308aa ? ? ? mov x0, x8 ? ? ? ? ? ? ? ? ?; int64_t arg1
│ ? ? ? ? ? 0x0000f0d4 ? ? ?40000094 ? ? ? bl fcn.0000f1d4 ? ? ? ? ? ? ; fcn.0000f1d4(0x0)
│ ? ? ? ? ? 0x0000f0d8 ? ? ?e80b40f9 ? ? ? ldr x8, [var_10h] ? ? ? ? ? ; aav.0x00000010
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; [0x10:4]=0xb70003
│ ? ? ? ? ? 0x0000f0dc ? ? ?e00700f9 ? ? ? str x0, [var_8h]
│ ? ? ? ? ? 0x0000f0e0 ? ? ?e00308aa ? ? ? mov x0, x8
│ ? ? ? ? ? 0x0000f0e4 ? ? ?e10740f9 ? ? ? ldr x1, [var_8h] ? ? ? ? ? ?; aav.0x00000008
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; [0x8:4]=0
│ ? ? ? ? ? 0x0000f0e8 ? ? ?e6feff97 ? ? ? bl fcn.0000ec80
│ ? ? ? ? ? 0x0000f0ec ? ? ?e00300f9 ? ? ? str x0, [sp]
│ ? ? ? ┌─< 0x0000f0f0 ? ? ?01000014 ? ? ? b 0xf0f4
│ ? ? ? │ ? ; CODE XREF from sym.Java_com_example_myapplication_MainActivity_stringFromJNI @ 0xf0f0
│ ? ? ? └─> 0x0000f0f4 ? ? ?a08300d1 ? ? ? sub x0, var_20h
│ ? ? ? ? ? 0x0000f0f8 ? ? ?2affff97 ? ? ? bl fcn.0000eda0
│ ? ? ? ? ? 0x0000f0fc ? ? ?48d03bd5 ? ? ? mrs x8, tpidr_el0
│ ? ? ? ? ? 0x0000f100 ? ? ?081540f9 ? ? ? ldr x8, [x8, 0x28] ? ? ? ? ?; aav.0x00000028
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; [0x28:4]=0x341f8
│ ? ? ? ? ? 0x0000f104 ? ? ?a9835ff8 ? ? ? ldur x9, [var_bp_8h]
│ ? ? ? ? ? 0x0000f108 ? ? ?080109eb ? ? ? subs x8, x8, x9
│ ? ? ? ┌─< 0x0000f10c ? ? ?a1010054 ? ? ? b.ne 0xf140 ? ? ? ? ? ? ? ? ; likely
│ ? ? ?┌──< 0x0000f110 ? ? ?01000014 ? ? ? b 0xf114
│ ? ? ?││ ? ; CODE XREF from sym.Java_com_example_myapplication_MainActivity_stringFromJNI @ 0xf110
│ ? ? ?└──> 0x0000f114 ? ? ?e00340f9 ? ? ? ldr x0, [sp]
│ ? ? ? │ ? 0x0000f118 ? ? ?fd7b46a9 ? ? ? ldp x29, x30, [var_60h]
│ ? ? ? │ ? 0x0000f11c ? ? ?ffc30191 ? ? ? add sp, sp, 0x70 ? ? ? ? ? ?; 0x178000
│ ? ? ? │ ? 0x0000f120 ? ? ?c0035fd6 ? ? ? ret
..
? ? ? ││ ? ; CODE XREF from unk @
│ ? ? ? │ ? ; CODE XREF from sym.Java_com_example_myapplication_MainActivity_stringFromJNI @ 0xf10c
└ ? ? ? └─> 0x0000f140 ? ? ?14ffff97 ? ? ? bl sym.imp.__stack_chk_fail ; void __stack_chk_fail(void) ; sym.std::__ndk1::basic_string_char__std::__ndk1::char_traits_char___std::__ndk1::allocator_char___::basic_string_decltype_nullptr___char_const
└ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; void __stack_chk_fail(void)
ARM處理器用到的指令集分為 ARM 和 THUMB 兩種。ARM指令長(zhǎng)度固定為32bit,THUMB指令長(zhǎng)度固定為16bit。上面代碼的所有指令都是32位的,所以都是ARM指令。
代碼分析
1. 開(kāi)辟堆??臻g`sub sp, sp, 0x70`
2. 存在一對(duì)數(shù)據(jù) `stp x29, x30, [var_60h]`
3. x29與[var_60h]相加 `add x29, var_60h`
4. 保存狀態(tài)tpidr_el0到x8寄存器 ?`mrs x8, tpidr_el0`
5. 將x8+0x28內(nèi)存中的值加載到x8寄存器 `ldr x8, [x8, 0x28] `
6. 將x8寄存器保存起來(lái),保存到var_bp_8h指向的內(nèi)存中
7. 將第一個(gè)參數(shù)x0保存到var_bp_8h指向的內(nèi)存中
8. 將第二個(gè)參數(shù)x1保存到var_0h_2指向的內(nèi)存中
9. 將x1寄存器指向只讀字符串"Hello from C++"
10. 將x8寄存器與var_20h相減法,把結(jié)果賦值給x8寄存器
11. 將x8賦值給x0
12. 將x8寄存器保存到var_18h指向的內(nèi)存中
13. 調(diào)用函數(shù)fcn.0000ef10,沒(méi)有處理返回值,暫時(shí)不用關(guān)注
14. 將第一個(gè)參數(shù)給x0寄存器,上面函數(shù)的返回值沒(méi)有什么實(shí)際的用途呀,這里直接把x0寄存器覆蓋了
15. 恢復(fù)x8寄存器的值
16. 將x0寄存器的值保存起來(lái),放到var_10h指向的內(nèi)存中
17. 將x8寄存器賦值給x0
18. 調(diào)用fcn.0000f1d4
19. 恢復(fù)x8寄存器的值
20. 將上述函數(shù)的返回值x0保存到var_8h指向的內(nèi)存中
21. 將x8賦值給x0
22. 將var_8h中的值賦值給x1寄存器
23. 調(diào)用函數(shù)fcn.0000ec80
24. 將返回值x0保存到sp指向的內(nèi)存中
25. 跳轉(zhuǎn)到0xf0f4,也就是下一條指令
26. 將x0與var_20h相減,結(jié)果賦值給x0
27. 調(diào)用fcn.0000eda0
28. 讀取tpidr_el0狀態(tài)到x8寄存器
29. 將x8+0x28內(nèi)存中的值加載到x8寄存器 `ldr x8, [x8, 0x28] `
30. 加載var_bp_8h中的值到x9寄存器
31. 判斷x8的值是否發(fā)生變化,如果發(fā)生變化,走失敗流程,這個(gè)應(yīng)該是使用cookie技術(shù)防止堆棧攻擊的技術(shù)
32. 如果沒(méi)有發(fā)生變化,跳轉(zhuǎn)到0xf114
33. 將sp內(nèi)存中的值加載到x0寄存器中,用作返回值
34. 恢復(fù)x29,x30的值
35. 恢復(fù)堆棧
36. ret返回
通過(guò)上面的分析,可知最終的返回值是通過(guò)調(diào)用函數(shù)fcn.0000ec80。這個(gè)函數(shù)其中的一個(gè)參數(shù)是字符串處理函數(shù)fcn.0000f1d4的返回值。另一個(gè)參數(shù)是x8的值,通過(guò)分析可知x8寄存器正是函數(shù)Java_com_example_myapplication_MainActivity_stringFromJNI的第一個(gè)參數(shù),類型是JNIEnv。由此推斷fcn.0000ec80很可能是JNIEnv相關(guān)函數(shù)。
查看fcn.0000ec80
? ? ? ? ? ?; CALL XREF from sym.Java_com_example_myapplication_MainActivity_stringFromJNI @ 0xf0e8
┌ 16: fcn.0000ec80 ();
│ ? ? ? ? ? 0x0000ec80 ? ? ?300100d0 ? ? ? adrp x16, obj.typeinfo_for_decltype_nullptr__const ; 0x34000
│ ? ? ? ? ? 0x0000ec84 ? ? ?119a46f9 ? ? ? ldr x17, [x16, 0xd30] ? ? ? ; [0x34d30:4]=0xeb50 fcn.0000eb50 ; "P\xeb"
│ ? ? ? ? ? 0x0000ec88 ? ? ?10c23491 ? ? ? add x16, x16, 0xd30 ? ? ? ? ; 0x34d30 ; "P\xeb"
└ ? ? ? ? ? 0x0000ec8c ? ? ?20021fd6 ? ? ? br x17
跳轉(zhuǎn)到0x34d30,通過(guò)pd命令查看相應(yīng)的內(nèi)容。很顯然這個(gè)函數(shù)就是NewStringUTF。這涉及到got表和plt表,在深入理解GOT覆寫技術(shù)?中對(duì)GOT表進(jìn)行了介紹。在后續(xù)文章中還會(huì)重點(diǎn)講解android got表。

使用pdg命令decompiler一下更加直觀。

查看fcn.0000ef10
? ? ? ? ? ?; CALL XREF from sym.Java_com_example_myapplication_MainActivity_stringFromJNI @ 0xf0c0
┌ 16: fcn.0000ef10 ();
│ ? ? ? ? ? 0x0000ef10 ? ? ?300100d0 ? ? ? adrp x16, obj.typeinfo_for_decltype_nullptr__const ; 0x34000
│ ? ? ? ? ? 0x0000ef14 ? ? ?113e47f9 ? ? ? ldr x17, [x16, 0xe78] ? ? ? ; [0x34e78:4]=0xeb50 fcn.0000eb50 ; "P\xeb"
│ ? ? ? ? ? 0x0000ef18 ? ? ?10e23991 ? ? ? add x16, x16, 0xe78 ? ? ? ? ; 0x34e78 ; "P\xeb"
└ ? ? ? ? ? 0x0000ef1c ? ? ?20021fd6 ? ? ? br x17
最終定位到basic_string<decltype(nullptr)>(char const*)。

**查看basic_string函數(shù)信息,可知有2個(gè)參數(shù),其中x0也就是參數(shù)1是x8寄存器的值,x1指向字符串"Hello from C++"**。這個(gè)函數(shù)的功能相當(dāng)于string.c_str()。c_str()函數(shù)返回一個(gè)指向正規(guī)C字符串的指針常量, 內(nèi)容與本string串相同。
[0x0000eb50]> pdf @ 0x0000f144
? ? ? ? ? ?; UNKNOWN XREF from aav.0x00001f0c @ +0x664
┌ 88: sym.std::__ndk1::basic_string_char__std::__ndk1::char_traits_char___std::__ndk1::allocator_char___::basic_string_decltype_nullptr___char_const (int64_t arg1, int64_t arg2);
│ ? ? ? ? ? ; var int64_t var_10h @ x29-0x10
│ ? ? ? ? ? ; var int64_t var_8h @ x29-0x8
│ ? ? ? ? ? ; var int64_t var_sp_8h @ sp+0x8
│ ? ? ? ? ? ; var int64_t var_sp_10h @ sp+0x10
│ ? ? ? ? ? ; var char *var_18h @ sp+0x18
│ ? ? ? ? ? ; var int64_t var_30h @ sp+0x30
│ ? ? ? ? ? ; var int64_t var_30h_2 @ sp+0x38
│ ? ? ? ? ? ; arg int64_t arg1 @ x0
│ ? ? ? ? ? ; arg int64_t arg2 @ x1
│ ? ? ? ? ? 0x0000f144 ? ? ?ff0301d1 ? ? ? sub sp, sp, 0x40 ? ? ? ? ? ?; std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >::basic_string<decltype(nullptr)>(char const*)
│ ? ? ? ? ? 0x0000f148 ? ? ?fd7b03a9 ? ? ? stp x29, x30, [var_30h]
│ ? ? ? ? ? 0x0000f14c ? ? ?fdc30091 ? ? ? add x29, var_30h
│ ? ? ? ? ? 0x0000f150 ? ? ?a0831ff8 ? ? ? stur x0, [var_8h] ? ? ? ? ? ; arg1
│ ? ? ? ? ? 0x0000f154 ? ? ?a1031ff8 ? ? ? stur x1, [var_10h] ? ? ? ? ?; arg2
│ ? ? ? ? ? 0x0000f158 ? ? ?a8835ff8 ? ? ? ldur x8, [var_8h]
│ ? ? ? ? ? 0x0000f15c ? ? ?e00308aa ? ? ? mov x0, x8
│ ? ? ? ? ? 0x0000f160 ? ? ?e80f00f9 ? ? ? str x8, [var_18h]
│ ? ? ? ? ? 0x0000f164 ? ? ?cbfeff97 ? ? ? bl fcn.0000ec90
│ ? ? ? ? ? 0x0000f168 ? ? ?a1035ff8 ? ? ? ldur x1, [var_10h]
│ ? ? ? ? ? 0x0000f16c ? ? ?a0035ff8 ? ? ? ldur x0, [var_10h]
│ ? ? ? ? ? 0x0000f170 ? ? ?e10b00f9 ? ? ? str x1, [var_sp_10h]
│ ? ? ? ? ? 0x0000f174 ? ? ?9fffff97 ? ? ? bl fcn.0000eff0
│ ? ? ? ? ? 0x0000f178 ? ? ?e80f40f9 ? ? ? ldr x8, [var_18h] ? ? ? ? ? ; aav.0x00000018
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; [0x18:4]=0xf050 pc ; "P\xf0"
│ ? ? ? ? ? 0x0000f17c ? ? ?e00700f9 ? ? ? str x0, [var_sp_8h]
│ ? ? ? ? ? 0x0000f180 ? ? ?e00308aa ? ? ? mov x0, x8
│ ? ? ? ? ? 0x0000f184 ? ? ?e10b40f9 ? ? ? ldr x1, [var_sp_10h] ? ? ? ?; aav.0x00000010
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; [0x10:4]=0xb70003
│ ? ? ? ? ? 0x0000f188 ? ? ?e20740f9 ? ? ? ldr x2, [var_sp_8h] ? ? ? ? ; aav.0x00000008
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; [0x8:4]=0
│ ? ? ? ? ? 0x0000f18c ? ? ?a1ffff97 ? ? ? bl fcn.0000f010
│ ? ? ? ? ? 0x0000f190 ? ? ?fd7b43a9 ? ? ? ldp x29, x30, [var_30h]
│ ? ? ? ? ? 0x0000f194 ? ? ?ff030191 ? ? ? add sp, sp, 0x40 ? ? ? ? ? ?; 0x178000
└ ? ? ? ? ? 0x0000f198 ? ? ?c0035fd6 ? ? ? ret
查看fcn.0000f1d4
? ? ? ? ? ?; CALL XREF from sym.Java_com_example_myapplication_MainActivity_stringFromJNI @ 0xf0d4
┌ 36: fcn.0000f1d4 (char *arg1);
│ ? ? ? ? ? ; var char *var_8h @ sp+0x8
│ ? ? ? ? ? ; var int64_t var_10h @ sp+0x10
│ ? ? ? ? ? ; var int64_t var_10h_2 @ sp+0x18
│ ? ? ? ? ? ; arg char *arg1 @ x0
│ ? ? ? ? ? 0x0000f1d4 ? ? ?ff8300d1 ? ? ? sub sp, sp, 0x20
│ ? ? ? ? ? 0x0000f1d8 ? ? ?fd7b01a9 ? ? ? stp x29, x30, [var_10h]
│ ? ? ? ? ? 0x0000f1dc ? ? ?fd430091 ? ? ? add x29, var_10h
│ ? ? ? ? ? 0x0000f1e0 ? ? ?e00700f9 ? ? ? str x0, [var_8h] ? ? ? ? ? ?; arg1
│ ? ? ? ? ? 0x0000f1e4 ? ? ?e00740f9 ? ? ? ldr x0, [var_8h] ? ? ? ? ? ?; aav.0x00000008
│ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?; [0x8:4]=0 ; int64_t arg1
│ ? ? ? ? ? 0x0000f1e8 ? ? ?d8020094 ? ? ? bl fcn.0000fd48
│ ? ? ? ? ? 0x0000f1ec ? ? ?fd7b41a9 ? ? ? ldp x29, x30, [var_10h]
│ ? ? ? ? ? 0x0000f1f0 ? ? ?ff830091 ? ? ? add sp, sp, 0x20 ? ? ? ? ? ?; 0x178000
└ ? ? ? ? ? 0x0000f1f4 ? ? ?c0035fd6 ? ? ? ret
通過(guò)分析大概推測(cè)是混淆函數(shù),沒(méi)什么實(shí)際的作用,從上面的代碼中可以能看出x0的值也就是返回值沒(méi)有發(fā)生任何的改變。
查看fcn.0000eda0
? ? ? ? ; CALL XREF from sym.Java_com_example_myapplication_MainActivity_stringFromJNI @ 0xf0f8
? ? ? ? ? ?; CALL XREF from sym.Java_com_example_myapplication_MainActivity_stringFromJNI @ +0xa4
┌ 16: fcn.0000eda0 ();
│ ? ? ? ? ? 0x0000eda0 ? ? ?300100d0 ? ? ? adrp x16, obj.typeinfo_for_decltype_nullptr__const ; 0x34000
│ ? ? ? ? ? 0x0000eda4 ? ? ?11e246f9 ? ? ? ldr x17, [x16, 0xdc0] ? ? ? ; [0x34dc0:4]=0xeb50 fcn.0000eb50 ; "P\xeb"
│ ? ? ? ? ? 0x0000eda8 ? ? ?10023791 ? ? ? add x16, x16, 0xdc0 ? ? ? ? ; 0x34dc0 ; "P\xeb"
└ ? ? ? ? ? 0x0000edac ? ? ?20021fd6 ? ? ? br x17
最終定位到~basic_string()方法。

IDA查看
通過(guò)下圖可知與上面的分析基本一致。

ARM指令和寄存器
ARM指令
MRS指令的格式為: MRS{條件} 通用寄存器,程序狀態(tài)寄存器(CPSR或SPSR) MRS指令用亍將程序狀態(tài)寄存器的內(nèi)容傳送到通用寄存器中。
STUR (SIMD&FP): Store SIMD&FP register (unscaled offset).
跳轉(zhuǎn)指令: B ;跳轉(zhuǎn)指令,可帶條件跳轉(zhuǎn)與cmp配合使用 BL ;帶返回的跳轉(zhuǎn)指令, 返回地址保存到LR(X30) BLR ; 帶返回的跳轉(zhuǎn)指令,跳轉(zhuǎn)到指令后邊跟隨寄存器中保存的地址(例:blr x8 ;跳轉(zhuǎn)到x8保存的地址中去執(zhí)行),并且把當(dāng)前PC+4回寫到X30。 BR: 與BLR差別在于有無(wú)回寫。 RET ;子程序返回指令,返回地址默認(rèn)保存在LR(X30)
ADRP Xd, lable(Address Page) 符號(hào)擴(kuò)展一個(gè)21位的offset, 向左移動(dòng)12位 PC的值的低12位 清零, 然后 把 這兩者相加, 結(jié)果寫入到Xd寄存器 用來(lái)得到一塊含有 lable的4KB對(duì)齊 內(nèi)存區(qū)域的base地址 (也就是說(shuō)lable所在的地址,一定落在這個(gè)4KB的內(nèi)存區(qū)域里, 指令助記符里Page也就是這個(gè)意思), 可用來(lái)尋址 +/- 4GB的范圍。
ARM寄存器
ARM64 有34個(gè)寄存器,包括31個(gè)通用寄存器、SP、PC、CPSR。 寄存器 | 位數(shù) | 描述 | -------- | ----- | ----- x0-x30 | 64| 通用寄存器,如果有需要可以當(dāng)做32bit使用:W0-W30 FP(X29) | 64| 保存棧幀地址(棧底指針) LR(x30) | 64|通常稱X30為程序鏈接寄存器,保存子程序結(jié)束后需要執(zhí)行的下一條指令 SP | 64 |保存棧指針,使用 SP/WSP來(lái)進(jìn)行對(duì)SP寄存器的訪問(wèn)。 PC |64|程序計(jì)數(shù)器,俗稱PC指針,總是指向即將要執(zhí)行的下一條指令,在arm64中,軟件是不能改寫PC寄存器的。 CPSR |64 |狀態(tài)寄存器
程序狀態(tài)寄存器
CPSR (Current Program Status Register),各個(gè)bit的含義如下圖:

SPSR (Saved Program Status Register),在異常狀態(tài)下使用,當(dāng)發(fā)生異常時(shí),會(huì)把CPSR的內(nèi)容寫入SPSR, 等異?;謴?fù)之后,又會(huì)把SPSR寫到CPSR中。
公眾號(hào)
更多內(nèi)容,歡迎關(guān)注我的微信公眾號(hào):無(wú)情劍客。
