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]方法
NSThread的start方法内部做了什么?的更多相关文章
- C# 多线程调用静态方法或者静态实例中的同一个方法-方法内部的变量是线程安全的
C# 多线程调用静态方法或者静态实例中的同一个方法-方法内部的变量是线程安全的 using System;using System.Threading;using System.Threading. ...
- 编写高质量代码改善C#程序的157个建议——建议144:一个方法只做一件事
建议144:一个方法只做一件事 “单一职责原则”(SRP)要求每一个类型只负责一件事情.我们将此概念扩展到方法上,就变成了:一个方法只做一件事. 回顾上一建议的代码,LocalInit和RemoteI ...
- UIView封装动画--iOS利用系统提供方法来做转场动画
UIView封装动画--iOS利用系统提供方法来做转场动画 UIViewAnimationOptions option; if (isNext) { option=UIViewAnimationOpt ...
- UIView封装动画--iOS利用系统提供方法来做关键帧动画
iOS利用系统提供方法来做关键帧动画 ios7以后才有用. /*关键帧动画 options:UIViewKeyframeAnimationOptions类型 */ [UIView animateKey ...
- UIView封装动画--iOS 利用系统提供方法来做弹性运动
iOS 利用系统提供方法来做弹性运动 /*创建弹性动画 damping:阻尼,范围0-1,阻尼越接近于0,弹性效果越明显 velocity:弹性复位的速度 */ [UIView animateWith ...
- 是否可以从一个static方法内部发出对非static方法的调用
不可以.因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方 法调用,而static方法调用时不需要创建对象,可以直接调用.也就是说,当一个static方法被调用时 ...
- C# 函数方法内部实现循环调用自身
//C# 函数方法内部实现循环调用自身 void TreeViewFresh(){ Action<TreeNodeCollection, MenuItem> addNode = (Tree ...
- 是否可以从一个static方法内部调用非static方法?
不可以.静态成员不能调用非静态成员. 非static方法属于对象,必须创建一个对象后,才可以在通过该对象来调用static方法.而static方法调用时不需要创建对象,通过类就可以调用该方法.也就是说 ...
- 220327_IDEA调试debug时step into看不了方法内部的解决办法
220327_问题解决_IDEA Debug时stepinto无法进入方法内部的解决方法 File Settings Build,Execution,Deployment Debugger Stepp ...
- List中的Contains方法内部其实是用对象的equals方法做比较,所以如果比较两个类就重写类的equals方法即可;而Set是调用equals和hashCode
public class Person { private String name; private int age; public String getName() { return name; } ...
随机推荐
- Amazon免费CE2基于docker部署nginx,并实现访问
在部署之前,请确保你已经申请好了CE2免费的服务器,网上的相关教程很多,可以自由参考. 一.使用xshell+公钥连接实例 1.打开xshell,导入密钥, 选择"工具" -> ...
- 【Java】多线程之实现Runnable接口
1 /** 2 * 3 */ 4 package com.raliable.chapter_0; 5 /** 6 * @author : Administrator 7 * @date :2022年4 ...
- Android记账本界面实现
<!--activity_main.xml-->1 <?xml version="1.0" encoding="utf-8"?> 2 & ...
- 【已解决】linux环境jps命令不显示进程
2021-09-28 10:26:42 问题描述: 输入jps后不显示进程 解决办法 1. cd /tmp/hsperfdata_root/ 2. ls 如果是空的 3. rm -rf hsperfd ...
- 6 HTML图片标签
6 图片标签 在HTML中,图像由标签定义的,它可以用来加载图片到html网页中显示.网页开发过程中,有三种图片格式被广泛应用到web里,分别是 jpg.png.gif. img标签的属性: /* s ...
- #Every-SG#HDU 3595 GG and MM
题目 有\(n\)个游戏,每个游戏只要能进行就必须进行, 对于每个游戏有两堆石子,每次可以将数量多的中取出小堆石子数量的整数倍, 无法操作者为负,问先手是否必胜 分析 如果单个游戏最大操作次数为奇数次 ...
- #后缀数组#洛谷 4051 [JSOI2007]字符加密
题目 分析 将字符串复制一份放入末尾,将其后缀排序之后 SA数组既然表示排名为\(i\)的后缀的起始位置, 那么只要它在\([1,len]\)范围内就是合法的, 那么输出以这个位置开头长度为\(len ...
- 开发人员使用HANA交付业务的学习路径
本文于2019年7月22日完成,发布在个人博客网站上. 考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来. 入门 编程规范. 开发环境使用方法. 基本语法,与其它同类软件的 ...
- JDK14中的java tools简介
目录 故事发生了 java tools简介 jaotc jar jarsigner java javac javadoc javap jcmd jconsole jdb jdeprscan jdeps ...
- std::thread 三:条件变量(condition_variable())
condition_variable . wait . notify_one . notify_all *:notify_one:通知(唤醒)一个线程 *:notify_all:通知( ...