NSThread的start方法内部做了什么?

下面是NSThread start方法的汇编码:

 1  1 1 ;Foundation`-[NSThread start]:
 2  2  2 ->  0x7fff2594f47f <+0>:   push   rbp
 3  3  3     0x7fff2594f480 <+1>:   mov    rbp, rsp
 4  4  4     0x7fff2594f483 <+4>:   push   r15
 5  5  5     0x7fff2594f485 <+6>:   push   r14
 6  6  6     0x7fff2594f487 <+8>:   push   r12
 7  7  7     0x7fff2594f489 <+10>:  push   rbx
 8  8  8     0x7fff2594f48a <+11>:  mov    r14, rsi
 9  9  9     0x7fff2594f48d <+14>:  mov    r15, rdi
10 10 10     0x7fff2594f490 <+17>:  mov    rax, qword ptr [rdi + 0x8];rid存储self,这里获取NSThread对象里面的_NSThreadData对象
11 11 11     0x7fff2594f494 <+21>:  mov    cl, byte ptr [rax + 0x37]
12 12 12     0x7fff2594f497 <+24>:  cmp    cl, 0xd;通过_NSThread对象里面的实例变量判断线程是否已经被启动过
13 13 13     0x7fff2594f49a <+27>:  jae    0x7fff2594f579            ; <+250>;如果已经被启动过了,跳转到<+250>处,也就是73行处抛出异常
14 14 14     0x7fff2594f4a0 <+33>:  mov    byte ptr [rax + 0x37], 0xd;回写启动过标志到_NSThreadData对象
15 15 15     0x7fff2594f4a4 <+37>:  mov    rbx, qword ptr [r15 + 0x8]
16 16 16     0x7fff2594f4a8 <+41>:  cmp    byte ptr [rbx + 0x36], 0x0
17 17 17     0x7fff2594f4ac <+45>:  je     0x7fff2594f4b7            ; <+56>
18 18 18     0x7fff2594f4ae <+47>:  mov    byte ptr [rbx + 0x37], 0xf
19 19 19     0x7fff2594f4b2 <+51>:  jmp    0x7fff2594f570            ; <+241>
20 20 20     0x7fff2594f4b7 <+56>:  cmp    byte ptr [rip + 0x6220e832], 0x0 ; _NSCStringCharToUnicharTable + 7 判断当前应用是否在多线程模式
21 21 21     0x7fff2594f4be <+63>:  jne    0x7fff2594f4fa            ; <+123>是的话跳转到<+123>,也就是34行处,不会发通知NSWillBecomeMultiThreadedNotification
22 22 22     0x7fff2594f4c0 <+65>:  mov    byte ptr [rip + 0x6220e829], 0x1 ; _NSCStringCharToUnicharTable + 7 如果不是多线程模式,回写标志1,发通知NSWillBecomeMultiThreadedNotification
23 23 23     0x7fff2594f4c7 <+72>:  mov    rdi, qword ptr [rip + 0x621f72c2] ; (void *)0x00007fff87b4f758: NSNotificationCenter
24 24 24     0x7fff2594f4ce <+79>:  mov    rsi, qword ptr [rip + 0x621ee9d3] ; "defaultCenter"
25 25 25     0x7fff2594f4d5 <+86>:  mov    rbx, qword ptr [rip + 0x5b02d974] ; (void *)0x00007fff50ba4400: objc_msgSend
26 26 26     0x7fff2594f4dc <+93>:  call   rbx
27 27 27     0x7fff2594f4de <+95>:  mov    rsi, qword ptr [rip + 0x621ef763] ; "postNotificationName:object:userInfo:"
28 28 28     0x7fff2594f4e5 <+102>: lea    rdx, [rip + 0x5b046e3c]   ; @"NSWillBecomeMultiThreadedNotification"
29 29 29     0x7fff2594f4ec <+109>: mov    rdi, rax
30 30 30     0x7fff2594f4ef <+112>: xor    ecx, ecx
31 31 31     0x7fff2594f4f1 <+114>: xor    r8d, r8d
32 32 32     0x7fff2594f4f4 <+117>: call   rbx
33 33 33     0x7fff2594f4f6 <+119>: mov    rbx, qword ptr [r15 + 0x8]
34 34 34     0x7fff2594f4fa <+123>: mov    al, byte ptr [rbx + 0x35]
35 35 35     0x7fff2594f4fd <+126>: test   al, al
36 36 36     0x7fff2594f4ff <+128>: je     0x7fff2594f523            ; <+164>
37 37 37     0x7fff2594f501 <+130>: add    rbx, 0x48
38 38 38     0x7fff2594f505 <+134>: cmp    al, -0x1
39 39 39     0x7fff2594f507 <+136>: movzx  eax, al
40 40 40     0x7fff2594f50a <+139>: mov    ecx, 0x15
41 41 41     0x7fff2594f50f <+144>: cmovne ecx, eax
42 42 42     0x7fff2594f512 <+147>: movsx  esi, cl
43 43 43     0x7fff2594f515 <+150>: mov    rdi, rbx
44 44 44     0x7fff2594f518 <+153>: xor    edx, edx
45 45 45     0x7fff2594f51a <+155>: call   0x7fff25af352c            ; symbol stub for: pthread_attr_set_qos_class_np
46 46 46     0x7fff2594f51f <+160>: mov    rbx, qword ptr [r15 + 0x8]
47 47 47     0x7fff2594f523 <+164>: lea    r12, [rbx + 0x88]
48 48 48     0x7fff2594f52a <+171>: add    rbx, 0x48
49 49 49     0x7fff2594f52e <+175>: mov    rdi, r15
50 50 50     0x7fff2594f531 <+178>: call   qword ptr [rip + 0x5b02d929] ; (void *)0x00007fff50bbec60: objc_retain
51 51 51     0x7fff2594f537 <+184>: lea    rdx, [rip + 0x96]         ; __NSThread__start__
52 52 52     0x7fff2594f53e <+191>: mov    rdi, r12
53 53 53     0x7fff2594f541 <+194>: mov    rsi, rbx
54 54 54     0x7fff2594f544 <+197>: mov    rcx, rax
55 55 55     0x7fff2594f547 <+200>: call   0x7fff25af3574            ; symbol stub for: pthread_create
56 56 56     0x7fff2594f54c <+205>: test   eax, eax
57 57 57     0x7fff2594f54e <+207>: je     0x7fff2594f570            ; <+241>
58 58 58     0x7fff2594f550 <+209>: mov    ebx, eax
59 59 59     0x7fff2594f552 <+211>: mov    rdi, r15
60 60 60     0x7fff2594f555 <+214>: mov    rsi, r14
61 61 61     0x7fff2594f558 <+217>: call   0x7fff2593542b            ; _NSMethodExceptionProem
62 62 62     0x7fff2594f55d <+222>: lea    rdi, [rip + 0x5b046d84]   ; @"%@: Thread creation failed with error %d"
63 63 63     0x7fff2594f564 <+229>: mov    rsi, rax
64 64 64     0x7fff2594f567 <+232>: mov    edx, ebx
65 65 65     0x7fff2594f569 <+234>: xor    eax, eax
66 66 66     0x7fff2594f56b <+236>: call   0x7fff25931294            ; NSLog
67 67 67     0x7fff2594f570 <+241>: pop    rbx
68 68 68     0x7fff2594f571 <+242>: pop    r12
69 69 69     0x7fff2594f573 <+244>: pop    r14
70 70 70     0x7fff2594f575 <+246>: pop    r15
71 71 71     0x7fff2594f577 <+248>: pop    rbp
72 72 72     0x7fff2594f578 <+249>: ret    
73 73 73     0x7fff2594f579 <+250>: mov    rbx, qword ptr [rip + 0x621f7150] ; (void *)0x00007fff87b502e8: NSString
74 74 74     0x7fff2594f580 <+257>: mov    rdi, r15
75 75 75     0x7fff2594f583 <+260>: mov    rsi, r14
76 76 76     0x7fff2594f586 <+263>: call   0x7fff2593542b            ; _NSMethodExceptionProem
77 77 77     0x7fff2594f58b <+268>: mov    rsi, qword ptr [rip + 0x621ee3fe] ; "stringWithFormat:"
78 78 78     0x7fff2594f592 <+275>: lea    rdx, [rip + 0x5b046d2f]   ; @"%@: attempt to start the thread again"
79 79 79     0x7fff2594f599 <+282>: mov    r14, qword ptr [rip + 0x5b02d8b0] ; (void *)0x00007fff50ba4400: objc_msgSend
80 80 80     0x7fff2594f5a0 <+289>: mov    rdi, rbx
81 81 81     0x7fff2594f5a3 <+292>: mov    rcx, rax
82 82 82     0x7fff2594f5a6 <+295>: xor    eax, eax
83 83 83     0x7fff2594f5a8 <+297>: call   r14
84 84 84     0x7fff2594f5ab <+300>: mov    rdi, qword ptr [rip + 0x621f717e] ; (void *)0x00007fff87a91f48: NSException
85 85 85     0x7fff2594f5b2 <+307>: mov    rcx, qword ptr [rip + 0x5b02cf27] ; (void *)0x00007fff80637d60: NSInvalidArgumentException
86 86 86     0x7fff2594f5b9 <+314>: mov    rdx, qword ptr [rcx]
87 87 87     0x7fff2594f5bc <+317>: mov    rsi, qword ptr [rip + 0x621ee565] ; "exceptionWithName:reason:userInfo:"
88 88 88     0x7fff2594f5c3 <+324>: mov    rcx, rax
89 89 89     0x7fff2594f5c6 <+327>: xor    r8d, r8d
90 90 90     0x7fff2594f5c9 <+330>: call   r14
91 91 91     0x7fff2594f5cc <+333>: mov    rdi, rax
92 92 92     0x7fff2594f5cf <+336>: call   0x7fff25af332e            ; symbol stub for: objc_exception_throw

上面的汇编代码总共分4部分:

第一部分:第10行到第13行,判断是当前的NSThread是否被启动过,如果已经启动过再次启动,就会抛出异常

第二部分:第14到第32行,启动线程前会判断当前应用使用已经是多线程状态了,如果还不是,就抛出通知NSWillBecomeMultiThreadedNotification;如果是不会抛出通知

第三部分:第33行到55行,调用pthread_create函数创建一个线程,并将__NSThread__start__函数作为pthread_create函数的第三个参数传递进去,而这个参数是线程的入口函数

第四部分:第55行到92行,主要是抛出两个异常,一个是线程创建失败异常,一个是线程重复启动异常。

上面的分析中,有一个__NSThread_start__函数,它是线程的入口函数,我们继续看看它里面的实现,汇编代码如下:

  1 Foundation`__NSThread__start__:
  2 ->  0x7fff2594f5d4 <+0>:    push   rbp
  3     0x7fff2594f5d5 <+1>:    mov    rbp, rsp
  4     0x7fff2594f5d8 <+4>:    push   r15
  5     0x7fff2594f5da <+6>:    push   r14
  6     0x7fff2594f5dc <+8>:    push   r13
  7     0x7fff2594f5de <+10>:   push   r12
  8     0x7fff2594f5e0 <+12>:   push   rbx
  9     0x7fff2594f5e1 <+13>:   sub    rsp, 0x228
 10     0x7fff2594f5e8 <+20>:   mov    r15, rdi
 11     0x7fff2594f5eb <+23>:   mov    rax, qword ptr [rip + 0x5b02d3ae] ; (void *)0x00007fff89cb95c0: __stack_chk_guard
 12     0x7fff2594f5f2 <+30>:   mov    rax, qword ptr [rax]
 13     0x7fff2594f5f5 <+33>:   mov    qword ptr [rbp - 0x30], rax
 14     0x7fff2594f5f9 <+37>:   lea    rdx, [rip + 0xfad]        ; __NSFinalizeThreadData
 15     0x7fff2594f600 <+44>:   mov    esi, 0xbc614e
 16     0x7fff2594f605 <+49>:   mov    edi, 0x1d
 17     0x7fff2594f60a <+54>:   call   0x7fff25af289c            ; symbol stub for: _CFSetTSD
 18     0x7fff2594f60f <+59>:   mov    edi, 0x1c
 19     0x7fff2594f614 <+64>:   mov    rsi, r15
 20     0x7fff2594f617 <+67>:   xor    edx, edx
 21     0x7fff2594f619 <+69>:   call   0x7fff25af289c            ; symbol stub for: _CFSetTSD
 22     0x7fff2594f61e <+74>:   lea    rdi, [rip + 0x6220b013]   ; threadsLock
 23     0x7fff2594f625 <+81>:   call   0x7fff25af35bc            ; symbol stub for: pthread_mutex_lock
 24     0x7fff2594f62a <+86>:   call   0x7fff25af361c            ; symbol stub for: pthread_self
 25     0x7fff2594f62f <+91>:   mov    rbx, rax
 26     0x7fff2594f632 <+94>:   cmp    qword ptr [rip + 0x6220d40e], -0x1 ; performSelector:onThread:withObject:waitUntilDone:modes:.sInvalidSystem + 3
 27     0x7fff2594f63a <+102>:  jne    0x7fff2594fa21            ; <+1101>
 28     0x7fff2594f640 <+108>:  mov    rdi, qword ptr [rip + 0x6220d409] ; __NSThreads.oAllThreads
 29     0x7fff2594f647 <+115>:  mov    rsi, rbx
 30     0x7fff2594f64a <+118>:  mov    rdx, r15
 31     0x7fff2594f64d <+121>:  call   0x7fff25af1f12            ; symbol stub for: CFDictionarySetValue
 32     0x7fff2594f652 <+126>:  mov    rax, qword ptr [r15 + 0x8]
 33     0x7fff2594f656 <+130>:  mov    byte ptr [rax + 0x37], 0xe
 34     0x7fff2594f65a <+134>:  lea    rdi, [rip + 0x6220afd7]   ; threadsLock
 35     0x7fff2594f661 <+141>:  call   0x7fff25af35c8            ; symbol stub for: pthread_mutex_unlock
 36     0x7fff2594f666 <+146>:  mov    rdi, r15
 37     0x7fff2594f669 <+149>:  call   qword ptr [rip + 0x5b02d7e9] ; (void *)0x00007fff50bbe940: objc_release
 38     0x7fff2594f66f <+155>:  mov    rdi, r15
 39     0x7fff2594f672 <+158>:  call   0x7fff25af33e8            ; symbol stub for: objc_sync_enter
 40     0x7fff2594f677 <+163>:  call   0x7fff25af2152            ; symbol stub for: CFRunLoopGetCurrent 这里会创建这个线程的RunLoop
 41     0x7fff2594f67c <+168>:  mov    qword ptr [rbp - 0x238], rax
 42     0x7fff2594f683 <+175>:  xorps  xmm0, xmm0
 43     0x7fff2594f686 <+178>:  lea    rdx, [rbp - 0x70]
 44     0x7fff2594f68a <+182>:  movaps xmmword ptr [rdx + 0x30], xmm0
 45     0x7fff2594f68e <+186>:  movaps xmmword ptr [rdx + 0x20], xmm0
 46     0x7fff2594f692 <+190>:  movaps xmmword ptr [rdx + 0x10], xmm0
 47     0x7fff2594f696 <+194>:  movaps xmmword ptr [rdx], xmm0
 48     0x7fff2594f699 <+197>:  mov    rax, qword ptr [r15 + 0x8]
 49     0x7fff2594f69d <+201>:  mov    rdi, qword ptr [rax + 0x38]
 50     0x7fff2594f6a1 <+205>:  mov    rsi, qword ptr [rip + 0x621ee1d0] ; "countByEnumeratingWithState:objects:count:"
 51     0x7fff2594f6a8 <+212>:  lea    rcx, [rbp - 0xf0]
 52     0x7fff2594f6af <+219>:  mov    r8d, 0x10
 53     0x7fff2594f6b5 <+225>:  mov    qword ptr [rbp - 0x208], rdi
 54     0x7fff2594f6bc <+232>:  call   qword ptr [rip + 0x5b02d78e] ; (void *)0x00007fff50ba4400: objc_msgSend
 55     0x7fff2594f6c2 <+238>:  mov    r12, rax
 56     0x7fff2594f6c5 <+241>:  test   rax, rax
 57     0x7fff2594f6c8 <+244>:  je     0x7fff2594f957            ; <+899>
 58     0x7fff2594f6ce <+250>:  lea    rax, [rbp - 0x70]
 59     0x7fff2594f6d2 <+254>:  mov    rax, qword ptr [rax + 0x10]
 60     0x7fff2594f6d6 <+258>:  mov    rax, qword ptr [rax]
 61     0x7fff2594f6d9 <+261>:  mov    qword ptr [rbp - 0x218], rax
 62     0x7fff2594f6e0 <+268>:  mov    rax, qword ptr [rip + 0x5b02d449] ; (void *)0x00007fff8062d6e0: kCFAllocatorSystemDefault
 63     0x7fff2594f6e7 <+275>:  mov    rax, qword ptr [rax]
 64     0x7fff2594f6ea <+278>:  mov    qword ptr [rbp - 0x230], rax
 65     0x7fff2594f6f1 <+285>:  xor    ebx, ebx
 66     0x7fff2594f6f3 <+287>:  mov    qword ptr [rbp - 0x220], r12
 67     0x7fff2594f6fa <+294>:  mov    rax, qword ptr [rbp - 0x60]
 68     0x7fff2594f6fe <+298>:  mov    rcx, qword ptr [rbp - 0x218]
 69     0x7fff2594f705 <+305>:  cmp    qword ptr [rax], rcx
 70     0x7fff2594f708 <+308>:  je     0x7fff2594f716            ; <+322>
 71     0x7fff2594f70a <+310>:  mov    rdi, qword ptr [rbp - 0x208]
 72     0x7fff2594f711 <+317>:  call   0x7fff25af3322            ; symbol stub for: objc_enumerationMutation
 73     0x7fff2594f716 <+322>:  mov    rax, qword ptr [rbp - 0x68]
 74     0x7fff2594f71a <+326>:  mov    r14, qword ptr [rax + 8*rbx]
 75     0x7fff2594f71e <+330>:  mov    rax, qword ptr [r15 + 0x8]
 76     0x7fff2594f722 <+334>:  cmp    qword ptr [rax + 0x40], 0x0
 77     0x7fff2594f727 <+339>:  jne    0x7fff2594f73d            ; <+361>
 78     0x7fff2594f729 <+341>:  mov    rdi, qword ptr [rip + 0x621f6fd8] ; (void *)0x00007fff87a930a0: NSMutableDictionary
 79     0x7fff2594f730 <+348>:  call   0x7fff25af3388            ; symbol stub for: objc_opt_new
 80     0x7fff2594f735 <+353>:  mov    rcx, qword ptr [r15 + 0x8]
 81     0x7fff2594f739 <+357>:  mov    qword ptr [rcx + 0x40], rax
 82     0x7fff2594f73d <+361>:  xorps  xmm0, xmm0
 83     0x7fff2594f740 <+364>:  movaps xmmword ptr [rbp - 0x100], xmm0
 84     0x7fff2594f747 <+371>:  movaps xmmword ptr [rbp - 0x110], xmm0
 85     0x7fff2594f74e <+378>:  movaps xmmword ptr [rbp - 0x120], xmm0
 86     0x7fff2594f755 <+385>:  movaps xmmword ptr [rbp - 0x130], xmm0
 87     0x7fff2594f75c <+392>:  mov    rdi, qword ptr [r14 + 0x20]
 88     0x7fff2594f760 <+396>:  mov    r8d, 0x10
 89     0x7fff2594f766 <+402>:  mov    qword ptr [rbp - 0x210], rdi
 90     0x7fff2594f76d <+409>:  mov    rsi, qword ptr [rip + 0x621ee104] ; "countByEnumeratingWithState:objects:count:"
 91     0x7fff2594f774 <+416>:  lea    rdx, [rbp - 0x130]
 92     0x7fff2594f77b <+423>:  lea    rcx, [rbp - 0x1b0]
 93     0x7fff2594f782 <+430>:  call   qword ptr [rip + 0x5b02d6c8] ; (void *)0x00007fff50ba4400: objc_msgSend
 94     0x7fff2594f788 <+436>:  mov    qword ptr [rbp - 0x228], rbx
 95     0x7fff2594f78f <+443>:  test   rax, rax
 96     0x7fff2594f792 <+446>:  je     0x7fff2594f90c            ; <+824>
 97     0x7fff2594f798 <+452>:  mov    r14, rax
 98     0x7fff2594f79b <+455>:  mov    rax, qword ptr [rbp - 0x120]
 99     0x7fff2594f7a2 <+462>:  mov    rax, qword ptr [rax]
100     0x7fff2594f7a5 <+465>:  mov    qword ptr [rbp - 0x248], rax
101     0x7fff2594f7ac <+472>:  mov    rax, qword ptr [rip + 0x621ee0fd] ; "objectForKey:"
102     0x7fff2594f7b3 <+479>:  mov    qword ptr [rbp - 0x250], rax
103     0x7fff2594f7ba <+486>:  mov    rax, qword ptr [rip + 0x621ee0cf] ; "setObject:forKey:"
104     0x7fff2594f7c1 <+493>:  mov    qword ptr [rbp - 0x240], rax
105     0x7fff2594f7c8 <+500>:  xor    r12d, r12d
106     0x7fff2594f7cb <+503>:  mov    rax, qword ptr [rbp - 0x120]
107     0x7fff2594f7d2 <+510>:  mov    rcx, qword ptr [rbp - 0x248]
108     0x7fff2594f7d9 <+517>:  cmp    qword ptr [rax], rcx
109     0x7fff2594f7dc <+520>:  je     0x7fff2594f7ea            ; <+534>
110     0x7fff2594f7de <+522>:  mov    rdi, qword ptr [rbp - 0x210]
111     0x7fff2594f7e5 <+529>:  call   0x7fff25af3322            ; symbol stub for: objc_enumerationMutation
112     0x7fff2594f7ea <+534>:  mov    rax, qword ptr [rbp - 0x128]
113     0x7fff2594f7f1 <+541>:  mov    rbx, qword ptr [rax + 8*r12]
114     0x7fff2594f7f5 <+545>:  mov    r13, r15
115     0x7fff2594f7f8 <+548>:  mov    rax, qword ptr [r15 + 0x8]
116     0x7fff2594f7fc <+552>:  mov    rdi, qword ptr [rax + 0x40]
117     0x7fff2594f800 <+556>:  mov    rsi, qword ptr [rbp - 0x250]
118     0x7fff2594f807 <+563>:  mov    rdx, rbx
119     0x7fff2594f80a <+566>:  call   qword ptr [rip + 0x5b02d640] ; (void *)0x00007fff50ba4400: objc_msgSend
120     0x7fff2594f810 <+572>:  mov    r15, rax
121     0x7fff2594f813 <+575>:  test   rax, rax
122     0x7fff2594f816 <+578>:  jne    0x7fff2594f8c1            ; <+749>
123     0x7fff2594f81c <+584>:  xorps  xmm0, xmm0
124     0x7fff2594f81f <+587>:  movaps xmmword ptr [rbp - 0x1d0], xmm0
125     0x7fff2594f826 <+594>:  movaps xmmword ptr [rbp - 0x1e0], xmm0
126     0x7fff2594f82d <+601>:  movaps xmmword ptr [rbp - 0x1f0], xmm0
127     0x7fff2594f834 <+608>:  movaps xmmword ptr [rbp - 0x200], xmm0
128     0x7fff2594f83b <+615>:  mov    qword ptr [rbp - 0x1c0], 0x0
129     0x7fff2594f846 <+626>:  lea    rax, [rip + 0x524]        ; __NSThreadPerformPerform
130     0x7fff2594f84d <+633>:  mov    qword ptr [rbp - 0x1b8], rax
131     0x7fff2594f854 <+640>:  mov    edi, 0x1
132     0x7fff2594f859 <+645>:  mov    esi, 0x8
133     0x7fff2594f85e <+650>:  call   0x7fff25af2d70            ; symbol stub for: calloc
134     0x7fff2594f863 <+655>:  mov    qword ptr [rbp - 0x1f8], rax
135     0x7fff2594f86a <+662>:  mov    rdi, qword ptr [rbp - 0x230]
136     0x7fff2594f871 <+669>:  xor    esi, esi
137     0x7fff2594f873 <+671>:  lea    rdx, [rbp - 0x200]
138     0x7fff2594f87a <+678>:  call   0x7fff25af2194            ; symbol stub for: CFRunLoopSourceCreate
139     0x7fff2594f87f <+683>:  mov    r15, rax
140     0x7fff2594f882 <+686>:  mov    rax, qword ptr [rbp - 0x1f8]
141     0x7fff2594f889 <+693>:  mov    qword ptr [rax], r15
142     0x7fff2594f88c <+696>:  mov    rdi, qword ptr [rbp - 0x238]
143     0x7fff2594f893 <+703>:  mov    rsi, r15
144     0x7fff2594f896 <+706>:  mov    rdx, rbx
145     0x7fff2594f899 <+709>:  call   0x7fff25af2134            ; symbol stub for: CFRunLoopAddSource
146     0x7fff2594f89e <+714>:  mov    rax, qword ptr [r13 + 0x8]
147     0x7fff2594f8a2 <+718>:  mov    rdi, qword ptr [rax + 0x40]
148     0x7fff2594f8a6 <+722>:  mov    rsi, qword ptr [rbp - 0x240]
149     0x7fff2594f8ad <+729>:  mov    rdx, r15
150     0x7fff2594f8b0 <+732>:  mov    rcx, rbx
151     0x7fff2594f8b3 <+735>:  call   qword ptr [rip + 0x5b02d597] ; (void *)0x00007fff50ba4400: objc_msgSend
152     0x7fff2594f8b9 <+741>:  mov    rdi, r15
153     0x7fff2594f8bc <+744>:  call   0x7fff25af2122            ; symbol stub for: CFRelease
154     0x7fff2594f8c1 <+749>:  mov    rdi, r15
155     0x7fff2594f8c4 <+752>:  call   0x7fff25af21a6            ; symbol stub for: CFRunLoopSourceSignal
156     0x7fff2594f8c9 <+757>:  inc    r12
157     0x7fff2594f8cc <+760>:  cmp    r12, r14
158     0x7fff2594f8cf <+763>:  mov    r15, r13
159     0x7fff2594f8d2 <+766>:  jb     0x7fff2594f7cb            ; <+503>
160     0x7fff2594f8d8 <+772>:  mov    r8d, 0x10
161     0x7fff2594f8de <+778>:  mov    rdi, qword ptr [rbp - 0x210]
162     0x7fff2594f8e5 <+785>:  mov    rsi, qword ptr [rip + 0x621edf8c] ; "countByEnumeratingWithState:objects:count:"
163     0x7fff2594f8ec <+792>:  lea    rdx, [rbp - 0x130]
164     0x7fff2594f8f3 <+799>:  lea    rcx, [rbp - 0x1b0]
165     0x7fff2594f8fa <+806>:  call   qword ptr [rip + 0x5b02d550] ; (void *)0x00007fff50ba4400: objc_msgSend
166     0x7fff2594f900 <+812>:  mov    r14, rax
167     0x7fff2594f903 <+815>:  test   rax, rax
168     0x7fff2594f906 <+818>:  jne    0x7fff2594f7ac            ; <+472>
169     0x7fff2594f90c <+824>:  mov    rbx, qword ptr [rbp - 0x228]
170     0x7fff2594f913 <+831>:  inc    rbx
171     0x7fff2594f916 <+834>:  mov    r12, qword ptr [rbp - 0x220]
172     0x7fff2594f91d <+841>:  cmp    rbx, r12
173     0x7fff2594f920 <+844>:  jb     0x7fff2594f6fa            ; <+294>
174     0x7fff2594f926 <+850>:  mov    r8d, 0x10
175     0x7fff2594f92c <+856>:  mov    rdi, qword ptr [rbp - 0x208]
176     0x7fff2594f933 <+863>:  mov    rsi, qword ptr [rip + 0x621edf3e] ; "countByEnumeratingWithState:objects:count:"
177     0x7fff2594f93a <+870>:  lea    rdx, [rbp - 0x70]
178     0x7fff2594f93e <+874>:  lea    rcx, [rbp - 0xf0]
179     0x7fff2594f945 <+881>:  call   qword ptr [rip + 0x5b02d505] ; (void *)0x00007fff50ba4400: objc_msgSend
180     0x7fff2594f94b <+887>:  mov    r12, rax
181     0x7fff2594f94e <+890>:  test   rax, rax
182     0x7fff2594f951 <+893>:  jne    0x7fff2594f6f1            ; <+285>
183     0x7fff2594f957 <+899>:  mov    rdi, r15
184     0x7fff2594f95a <+902>:  call   0x7fff25af33ee            ; symbol stub for: objc_sync_exit
185     0x7fff2594f95f <+907>:  mov    edi, 0xa
186     0x7fff2594f964 <+912>:  call   0x7fff25895fa4            ; NSPushAutoreleasePool
187     0x7fff2594f969 <+917>:  mov    r14, rax
188     0x7fff2594f96c <+920>:  mov    rsi, qword ptr [rip + 0x621eeb25] ; "name"
189     0x7fff2594f973 <+927>:  mov    rdi, r15
190     0x7fff2594f976 <+930>:  call   qword ptr [rip + 0x5b02d4d4] ; (void *)0x00007fff50ba4400: objc_msgSend
191     0x7fff2594f97c <+936>:  test   rax, rax
192     0x7fff2594f97f <+939>:  je     0x7fff2594f999            ; <+965>
193     0x7fff2594f981 <+941>:  mov    rsi, qword ptr [rip + 0x621ee0a0] ; "UTF8String"
194     0x7fff2594f988 <+948>:  mov    rdi, rax
195     0x7fff2594f98b <+951>:  call   qword ptr [rip + 0x5b02d4bf] ; (void *)0x00007fff50ba4400: objc_msgSend
196     0x7fff2594f991 <+957>:  mov    rdi, rax
197     0x7fff2594f994 <+960>:  call   0x7fff25af3628            ; symbol stub for: pthread_setname_np
198     0x7fff2594f999 <+965>:  mov    rdi, qword ptr [rip + 0x621f6df0] ; (void *)0x00007fff87b4f758: NSNotificationCenter
199     0x7fff2594f9a0 <+972>:  mov    rsi, qword ptr [rip + 0x621ee501] ; "defaultCenter"
200     0x7fff2594f9a7 <+979>:  mov    rbx, qword ptr [rip + 0x5b02d4a2] ; (void *)0x00007fff50ba4400: objc_msgSend
201     0x7fff2594f9ae <+986>:  call   rbx
202     0x7fff2594f9b0 <+988>:  mov    rsi, qword ptr [rip + 0x621ef291] ; "postNotificationName:object:userInfo:"
203     0x7fff2594f9b7 <+995>:  lea    rdx, [rip + 0x5b0469ca]   ; @"_NSThreadDidStartNotification" 会有一个通知抛出来
204     0x7fff2594f9be <+1002>: mov    rdi, rax
205     0x7fff2594f9c1 <+1005>: mov    rcx, r15
206     0x7fff2594f9c4 <+1008>: xor    r8d, r8d
207     0x7fff2594f9c7 <+1011>: call   rbx
208     0x7fff2594f9c9 <+1013>: mov    rdi, r14
209     0x7fff2594f9cc <+1016>: call   0x7fff25895fae            ; NSPopAutoreleasePool
210     0x7fff2594f9d1 <+1021>: mov    rax, qword ptr [r15 + 0x8]
211     0x7fff2594f9d5 <+1025>: cmp    byte ptr [rax + 0x36], 0x0
212     0x7fff2594f9d9 <+1029>: jne    0x7fff2594f9eb            ; <+1047>
213     0x7fff2594f9db <+1031>: mov    rsi, qword ptr [rip + 0x621f0a0e] ; "main" 调用NSThread对象的main方法
214     0x7fff2594f9e2 <+1038>: mov    rdi, r15
215     0x7fff2594f9e5 <+1041>: call   qword ptr [rip + 0x5b02d465] ; (void *)0x00007fff50ba4400: objc_msgSend
216     0x7fff2594f9eb <+1047>: mov    rdi, qword ptr [rip + 0x621f6ece] ; (void *)0x00007fff87b504c8: NSThread
217     0x7fff2594f9f2 <+1054>: mov    rsi, qword ptr [rip + 0x621f0f9f] ; "exit" 调用NSThread对象的exit方法
218     0x7fff2594f9f9 <+1061>: call   qword ptr [rip + 0x5b02d451] ; (void *)0x00007fff50ba4400: objc_msgSend
219     0x7fff2594f9ff <+1067>: mov    rax, qword ptr [rip + 0x5b02cf9a] ; (void *)0x00007fff89cb95c0: __stack_chk_guard
220     0x7fff2594fa06 <+1074>: mov    rax, qword ptr [rax]
221     0x7fff2594fa09 <+1077>: cmp    rax, qword ptr [rbp - 0x30]
222     0x7fff2594fa0d <+1081>: jne    0x7fff2594fa39            ; <+1125>
223     0x7fff2594fa0f <+1083>: add    rsp, 0x228
224     0x7fff2594fa16 <+1090>: pop    rbx
225     0x7fff2594fa17 <+1091>: pop    r12
226     0x7fff2594fa19 <+1093>: pop    r13
227     0x7fff2594fa1b <+1095>: pop    r14
228     0x7fff2594fa1d <+1097>: pop    r15
229     0x7fff2594fa1f <+1099>: pop    rbp
230     0x7fff2594fa20 <+1100>: ret    
231     0x7fff2594fa21 <+1101>: lea    rdi, [rip + 0x6220d020]   ; __NSThreads.onceToken
232     0x7fff2594fa28 <+1108>: lea    rsi, [rip + 0x5b033191]   ; __block_literal_global
233     0x7fff2594fa2f <+1115>: call   0x7fff25af2f08            ; symbol stub for: dispatch_once
234     0x7fff2594fa34 <+1120>: jmp    0x7fff2594f640            ; <+108>
235     0x7fff2594fa39 <+1125>: call   0x7fff25af2c1a            ; symbol stub for: __stack_chk_fail
236     0x7fff2594fa3e <+1130>: jmp    0x7fff2594fa4a            ; <+1142>
237     0x7fff2594fa40 <+1132>: jmp    0x7fff2594fa4a            ; <+1142>
238     0x7fff2594fa42 <+1134>: jmp    0x7fff2594fa4a            ; <+1142>
239     0x7fff2594fa44 <+1136>: jmp    0x7fff2594fa4a            ; <+1142>
240     0x7fff2594fa46 <+1138>: jmp    0x7fff2594fa4a            ; <+1142>
241     0x7fff2594fa48 <+1140>: jmp    0x7fff2594fa4a            ; <+1142>
242     0x7fff2594fa4a <+1142>: mov    rbx, rax
243     0x7fff2594fa4d <+1145>: jmp    0x7fff2594fa57            ; <+1155>
244     0x7fff2594fa4f <+1147>: jmp    0x7fff2594fa51            ; <+1149>
245     0x7fff2594fa51 <+1149>: mov    rbx, rax
246     0x7fff2594fa54 <+1152>: mov    r15, r13
247     0x7fff2594fa57 <+1155>: mov    rdi, r15
248     0x7fff2594fa5a <+1158>: call   0x7fff25af33ee            ; symbol stub for: objc_sync_exit
249     0x7fff2594fa5f <+1163>: mov    rdi, rbx
250     0x7fff2594fa62 <+1166>: call   0x7fff25af2b5a            ; symbol stub for: _Unwind_Resume
251     0x7fff2594fa67 <+1171>: ud2    

上面的汇编代码有点长,但是只需要注意三点:

1 第40行,为线程创建了对应的RunLoop;

2 第203行,会有一个通知抛出来:_NSThreadDidStartNotification

3 第213行会调用-[NSThread main]方法,main方法执行完成之后,217行会调用+[NSThread exit]方法

原文地址:https://www.cnblogs.com/chaoguo1234/p/13284367.html