美文网首页
Swift汇编分析闭包扩展

Swift汇编分析闭包扩展

作者: oldmonster | 来源:发表于2021-07-01 14:09 被阅读0次

在上篇文章中我们分析了闭包中捕获了一个外部变量时其底层的参数传递逻辑,那么如果捕获两个外部变量时呢,其又是怎么传参的。

typealias Fn = (Int) -> (Int, Int)

func getFn() -> Fn {
    var a = 1
    var b = 2
    func plus(_ i: Int) -> (Int, Int) {
        a += i
        b += i * 2
        return (a, b)
    }
    return plus
}
//rax(函数地址)
//16 = 8 + 8
var fn = getFn()
fn(10)

同样我们在 return plus处断点,然后进入到汇编代码。

图1
我们知道在return之前,会将外部变量捕获并拷贝到堆空间,那么必然会alloc分配空间,此时我们直接找关键信息即可。但是这时我们发现有3个alloc,我们先不管,看第19行,可以看到将1放入到了0x10(%rax)中,而rax中存放的是我们分配在堆空间的地址,此时往后移16个字节。也就是直接写入到第3位8字节。

同理我们直接看第2个 alloc,可以得其将b放入到空间。

图2
这里我们看第三个alloc(后文称之为变量x),同样分配的堆空间的地址是通过rax返回的,此时会先将-0x30(%rbp)的数据放入到rcx中,而-0x30(%rbp)可以参考图1的第23行处,也就是给a分配堆空间后将其也放入到了-0x30(%rbp)中,而图2中可以知道rcx中的地址就是变量a的地址,而在41行处将该地址给了0x10(%rax),可以知道这里是直接将变量a赋值给了x的第3个8字节,也就是变量x持有了变量a,同样第42行和43行可知将变量b赋值给了变脸x的第4个8字节。 图3
看第45行处可以知道,此时将变量c放在了-0x50(%rbp)中,而在第50行处又放在了寄存器rdx中,从之前的文章中我们也知道寄存器rdx可以存放函数参数。

此时回到调用getFn处,这里的传参逻辑与捕获一个外部变量一致,
可参考前文Swift汇编分析闭包-调用原理

相关文章

  • Swift汇编分析闭包扩展

    在上篇文章中我们分析了闭包中捕获了一个外部变量时其底层的参数传递逻辑,那么如果捕获两个外部变量时呢,其又是怎么传参...

  • Swift汇编分析闭包-调用原理

    在《Swift汇编分析闭包-内存布局》[https://www.jianshu.com/p/bc5c595950c...

  • Swift汇编分析闭包-内存布局

    1、闭包表达式与闭包 闭包表达式也就是定义一个函数。一般我们可以通过func定义一个函数,也可以通过闭包表达式定义...

  • 从零学习Swift 06:汇编分析闭包本质

    在上一篇我们已经了解了闭包表达式和闭包.今天我们就通过汇编分析一下闭包的本质. 我们通过普通的函数类型的变量和闭包...

  • 汇编分析闭包本质

    引用类型的赋值操作 值类型、引用类型的let 嵌套类型 枚举、结构体、类都可以定义方法 思考?: 方法占用实例对象...

  • Swift-闭包

    Swift 闭包 函数 ()->() Swift 中的闭包和 Objective-C 中的 block 类似,闭包...

  • Swift闭包和函数

    函数在Swift中只是一种特殊的闭包,闭包在Swift语言中是一等公民,支持闭包嵌套和闭包传递。Swift中的闭包...

  • swift4 闭包

    swift 闭包 闭包:swift 中 函数是闭包的一种类似于oc的闭包闭包表达式(匿名函数) -- 能够捕获上下...

  • Swift中的闭包

    在Swift中有两种闭包,逃逸闭包(@escaping)和非逃逸闭包(@nonescaping)。从Swift 3...

  • 100 Days of Swift - Day 06 - 闭包(

    100 Days of Swift - Day 06 - 闭包Closures 6.1 闭包 Swift函数也属于...

网友评论

      本文标题:Swift汇编分析闭包扩展

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