寄存器
? ? ? 所謂寄存器(register),它是CPU內(nèi)部用來存放數(shù)據(jù)的一些小型存儲區(qū)域,用來暫時存放參與運算的數(shù)據(jù)和運算結(jié)果。(寄存器是CPU的組成部分萝喘,因為在CPU內(nèi),所以CPU對其讀寫速度是最快的,不需要IO傳輸)阁簸。IA-32構(gòu)架提供了16個基本寄存器爬早,這16個基本寄存器可以歸納為如下幾類:
通用寄存器
段寄存器
狀態(tài)和控制寄存器
指令寄存器
在這里我們主要介紹一下通用寄存器。
通用寄存器(x64)
? ? ? ?在 64-bit 模式下启妹,有16個通用寄存器筛严,但是這16個寄存器是兼容32位模式的,32位方式下寄存器名分別為
eax翅溺、 ebx脑漫、 ecx、edx咙崎、 edi优幸、 esi、 ebp褪猛、 esp网杆、 r8d – r15d
在64位模式下,他們被擴展為
rax伊滋、 rbx碳却、 rcx、rdx笑旺、 rdi昼浦、rsi、 rbp筒主、 rsp关噪、r8 – r15
?? ? ? 通用寄存器在我們的程序運行中所做的事可以簡單地總結(jié)為每個函數(shù)(方法)執(zhí)行時暫時存放參數(shù)和返回值。每個參數(shù)對應(yīng)的寄存器的關(guān)系為:
第一個參數(shù):RDI
第二個參數(shù):RSI
第三個參數(shù):RDX
第四個參數(shù): ?RCX
第五個參數(shù):R8
第六個參數(shù):R9
超過7個以及上的參數(shù)會被分配到進(jìn)程的棧區(qū)
返回值: RAX
舉個例子:
NSString *myName = @"George";
NSLog("Hello world! I'm%@, i'm %f years old, %@", myName, 22, @"Nice to meet you!");
在運行NSLog這個方法的時候乌妙,各寄存器對應(yīng)的參數(shù)是:
RDI =@"Hello world! I'm%@, i'm %f years old, %@";
RSI =@"George";
RDX = 22;
RCX =@"Nice to meet you!";
當(dāng)NSLog方法執(zhí)行結(jié)束后使兔,這些寄存器里的值會隨著其它方法的調(diào)用而改變。
OC中的寄存器
? ? ? ? 我們都知道OC這門語言是使用消息派發(fā)機制藤韵,大部分的函數(shù)方法調(diào)用都是通過C函數(shù)msg_send實現(xiàn)虐沥,對于msg_send的使用,這個函數(shù)的第一個參數(shù)是消息的發(fā)送者泽艘,第二個參數(shù)是選擇器(Selector)欲险,接下來就是不定數(shù)量的參數(shù)。舉個例子:
NSString *test = ["My name is" stringByAppendingString:"George"];
對于上面這個表達(dá)式匹涮,編譯器會轉(zhuǎn)換為以下:
msg_send(@"My name is", @"stringByAppendingString", @"George");
? ? ? ?在這里方法stringByAppendingString:的第一個參數(shù)(只有一個)其實對應(yīng)的是通用寄存器的第三個--RDX盯荤。
? ? ? ?因為OC語言特性的原因,通常方法中的參數(shù)所對應(yīng)的寄存器都是從第三個開始遞增存儲焕盟。相比之下,swift并不是使用消息派發(fā)機制,因此脚翘,第一個參數(shù)所對應(yīng)的寄存器就是RDI灼卢。