美文网首页Swift
Swift Day07 闭包探索

Swift Day07 闭包探索

作者: 望穿秋水小作坊 | 来源:发表于2020-12-01 22:14 被阅读0次

    一、闭包

    1. 请问下面代码的输出?
    问题
    • 输出 11 14
    • num 是在 getFn 调用,并且 return plus 之前捕获的
    2. 下面代码会对 person1 进行捕获吗?
    题目
    • 从汇编来看不会捕获,fn1 后 8 个字节存放了 person1 的地址值
    3. 下面函数打印什么?
    image.png
    • 打印 1 2 3
    • 应该是三次驳货

    二、探索普通函数变量的内存放着什么?

    1. 首先我们探索一下,一个正常的普通函数变量,它所占据的字节大小?
    func sum(_ v1: Int, _ v2: Int) -> Int { v1 + v2 }
    var fn = sum
    print(MemoryLayout.stride(ofValue: fn))
    // 输出: 16
    
    • 输出 16,表示普通函数,Swift 给他分配了 16 个字节
    • 按照我们的理解,正常情况下一个函数的地址仅需要 8 个字节,那么 16 个字节到底放着什么呢?
    2. 我们在上题函数的 print行 打上断点,进入汇编模式
    汇编图
    • %rcx 是 sum 函数的地址,赋值给了 fn 的前 8 个字节
    • 0x0 赋值给了 fn 的后 8 个字节
    • 另外我们可以计算 sum 的地址,然后打印 sum 的地址,两者一致,表示我们的猜想正确
    侧面证明

    三、探索闭包变量的内存放着什么?

    1. 闭包变量代码如下
    闭包变量
    • 进入汇编模式,查看 fn116 字节放着什么?
    汇编
    • 从汇编代码结合 xcode 提示,我们知道%rax 赋值给了 fn1 的前 8 个字节
    • %rdx 赋值给了 fn1 的后 8 个字节
    2. 接下来我们要弄懂 %rax 和 %rdx 分别存放什么?
    • %rax 和 %rdx 通常放着函数的返回值,所以我们要弄懂 callq 函数里面给这两个寄存器放了啥?

    • 所以我们需要在 return plus 行打上断点


      汇编以及分析
    • register read rax 查看获得 rax = 0x0000000100000e80

    • register read rdx 查看获得 rdx= 0x0000000100575170

    3. 接下来我们要继续跟进,确认 %rdx 到底存放什么?
    • 我们进入 callq 0x100000ea6
    4. 接下来我们要继续跟进,确认 %rax 到底存放什么?是否真的是 plus 地址?
    5. 太难了,这篇文章猝死了。

    相关文章

      网友评论

        本文标题:Swift Day07 闭包探索

        本文链接:https://www.haomeiwen.com/subject/ikoswktx.html