zoukankan      html  css  js  c++  java
  • 反汇编objc分析__block

    "You can specify that an imported variable be mutable—that is, read-write— by applying the __block storage type modifier."文档已经清楚说明了它的作用。反汇编就是要看个究竟。

    __block类型有着它自己的storage,是blocks编程的一部分,今天先来看一下它如何做storage的。

    我们定义如下:

    NSString* c = [@"ab" stringByAppendingString:@"c"];
        __block NSInteger bi = 0;
        __block NSString* bc = c;

    得到反汇编代码:

    0x10699054a <+90>:  movq   0x14bf7(%rip), %rsi       ; "stringByAppendingString:"
        0x106990551 <+97>:  leaq   0x13da8(%rip), %rdi       ; @"ab"
        0x106990558 <+104>: leaq   0x13dc1(%rip), %rdx       ; @"'c'"
        0x10699055f <+111>: movq   -0xf0(%rbp), %rcx
        0x106990566 <+118>: movq   %rax, -0xf8(%rbp)
        0x10699056d <+125>: callq  *%rcx
        0x10699056f <+127>: movq   %rax, -0x28(%rbp)
    ->  0x106990573 <+131>: movq   $0x0, -0x48(%rbp)
        0x10699057b <+139>: leaq   -0x48(%rbp), %rax
        0x10699057f <+143>: movq   %rax, -0x40(%rbp)
        0x106990583 <+147>: movl   $0x20000000, -0x38(%rbp)
        0x10699058a <+154>: movl   $0x20, -0x34(%rbp)
        0x106990591 <+161>: movq   $0x0, -0x30(%rbp)
        0x106990599 <+169>: movq   $0x0, -0x78(%rbp)
        0x1069905a1 <+177>: leaq   -0x78(%rbp), %rax
        0x1069905a5 <+181>: movq   %rax, -0x70(%rbp)
        0x1069905a9 <+185>: movl   $0x52000000, -0x68(%rbp)
        0x1069905b0 <+192>: movl   $0x30, -0x64(%rbp)
        0x1069905b7 <+199>: leaq   -0x21e(%rip), %rax        ; __Block_byref_object_copy_ at ViewController.mm:74
        0x1069905be <+206>: movq   %rax, -0x60(%rbp)
        0x1069905c2 <+210>: leaq   -0x1e9(%rip), %rax        ; __Block_byref_object_dispose_ at ViewController.mm:74
        0x1069905c9 <+217>: movq   %rax, -0x58(%rbp)
        0x1069905cd <+221>: movq   -0x28(%rbp), %rax
        0x1069905d1 <+225>: movq   %rax, -0x50(%rbp)

    很容易就看到两处构造对像的地方,没有错就是__block NSInteger bi和__block NSString* bc。这样就可以写出反c++伪代码:

    __Block_byref_object_copy_的汇编简单不贴了,_Block_object_assign就是根据最后一个标志参数选择执行_Block_retain,_Block_assign。此方法是被Block定义(就是NSBlock的一种),在构造私有调用栈时调用的。
    另一个__Block_byref_object_dispose_就是__block在析构里调用的。
    __block storage的地址被压入NSBlock的私有调用栈,地址不能改变,但是__block storage不在私有栈中,所以被它包装起来的真正的变量可以被修改。
    例如NSString*, int在NSBlock的私有调用栈中分别是NSString* const, int count, 而__block NSString*, __block int则是__block<NSString*>* const, __block<int>* const。

    上一篇介绍了《逆向分析objc,所有类的信息都能在动态调试中获取》。

    最后,多谢大家观看本篇文章。下一篇将分析block的反汇编,还会看到__block变量是如何被block使用的。

    更正修改:20150116
        :伪代码中少了一个成员,这个成员作用是__block变量从stack-based中脱离后,真实的指向(,或叫做重定向)。
  • 相关阅读:
    vue分页效果
    百度联想
    【java基础之jdk源码】集合类
    【java基础之jdk源码】Object
    深入理解abstract class和interface
    mysql索引类型 normal, unique, full text
    JSP中两种include的区别
    详解mysql int类型的长度值问题
    《Think in JAVA》之每日一读(initianlize)——2013/11/12、13
    探索ORM ————iBati(一)
  • 原文地址:https://www.cnblogs.com/bbqzsl/p/5126119.html
Copyright © 2011-2022 走看看