概览
我们在上一篇
- Swift 从获取所有 NSObject 对象聊起:ObjC、汇编语言以及底层方法调用链(四)
博文中“一头扎入”系统底层,从汇编语言的角度详细介绍了 iOS 运行时(Runtime)方法调用栈的跟踪、以及如何恣意更改方法调用链走向等理论知识。
“纸上来得终觉浅,绝知此事要躬行”,而在本篇我们就来实际拥抱汇编代码,“撸起袖子秀上一波”吧。
在本篇博文中,您将学到如下内容:
- 概览
- 8. 走进 ARM64 汇编的世界
- 9. 让汇编代码告别“傻白甜”
- 10. 番外篇:另一种更简洁的方案
- 总结
这是本系列最后一篇文章,我们的大冒险已接近尾声,收官之战就在眼前!
那小伙伴们怎能止步不前呢?让我们马上圆满本次探险之旅吧!
Let’s put an end to it!!!😉
8. 走进 ARM64 汇编的世界
承接上一篇博文,我们首先新建一个汇编源代码文件,文件后缀应该为 .s。
Xcode 对汇编语法的支持实在“强差人意”,如果可能的话大家可以找一个优秀的汇编代码编辑器。
比如 Sublime Text 或 VS Code 等都是优选。
将下面的代码“塞入”新建的汇编源代码文件里:
.text.globl _asm_test.p2align 2
_asm_test:// 申请堆栈空间并保存 fp、lr 寄存器sub sp, sp, #0xF0stp x29, x30, [sp, #0xE0]add x29, sp, #0xE0// 保存任何可能被覆写的寄存器str x0,[x29, #-0x8]str x1,[x29, #-0x10]str x2,[x29, #-0x18]str x3,[x29, #-0x20]str x4,[x29, #-0x28]str x5,[x29, #-0x30]str x6,[x29, #-0x38]str x7,[x29, #-0x40]str x8,[x29, #-0x48]str x9,[x29, #-0x50]str x10,[x29, #-0x58]str x11,[x29, #-0x60]str x16,[x29, #-0x68]str x20,[x29, #-0x70]// 施展我们的“精细外科手术”:将 thunk() 中返回地址改为原地址后两条指令的地址ldr x1,[x29]add x1,x1,#0x8ldr x0,[x1]add x0,x0,#0x8str x0,[x1]/* 拓展功能,待实现*/// 平衡 thunk() 中原来 swift_retain() 方法的调用ldr x16,[x29, #-0x68]ldr x0,[x29, #-0x70