下面是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]方法