本篇是我本人博客中的專題“追根溯源 從C++到匯編”中的開篇。這是我第一次嘗試寫一個系列的文章出來與大家分享。如果有什么疏漏,歡迎大家指正。
為了闡述C++和匯編的關(guān)系,我覺著有必要簡單介紹下匯編知識和一些計算機的基本組成。本篇的內(nèi)容盡量保持簡短。本篇的目的是為了后續(xù)的講解做一個基礎(chǔ)性的鋪墊與簡介,點到即止。
本文假定讀者沒有任何匯編基礎(chǔ)知識。如果有讀者對匯編很熟悉,可以略過本篇,參看系列后續(xù)的文章。
疑惑:程序到底是怎么執(zhí)行的
現(xiàn)代計算機自圖靈機理論誕生以來經(jīng)歷了高速發(fā)展?;ヂ?lián)網(wǎng)時代,網(wǎng)絡(luò)和移動平臺正在深刻地改變這個社會。作為程序員,我們每天都在產(chǎn)出代碼,這些代碼在特定的平臺和運行時系統(tǒng)支撐下運行,我們都早已習(xí)以為常。
但是如果你問一個程序員:你寫的程序為什么能執(zhí)行?大概他會一愣,然后拋出各種理論:因為編譯器啊,因為jvm運行時啊,因為語言機制啊等等不一而足。其實這個問題就好比你去問一個大學(xué)生:1+1=2是個什么原理。也許在程序員看來,“程序為什么能運行”根本就不是問題,或者說算是個哲學(xué)問題?
其實很多時候,我們都不會去思考這種問題,因為它太基礎(chǔ),但是今天,我想嘗試從匯編的角度解釋下這個問題。
從匯編層面解釋程序執(zhí)行
1. cpu工作原理
這個話題扯開來說很大,我們盡量簡單點理解它。
1.1 機器碼與指令集
我們都知道,cpu是計算機的邏輯運算核心。我們寫的程序代碼,在編譯為二進制后,最終會由cpu來執(zhí)行(當(dāng)然,gpu現(xiàn)在也能執(zhí)行運算,這個我們暫且不表)。那為什么cpu能夠理解二進制的0101代表什么意思?因為cpu指令集。
不同的cpu在設(shè)計的時候,就被設(shè)計為支持某種指令的編碼格式,我們稱之為cpu指令集。不同的cpu支持不同的指令集。比如我們經(jīng)常聽到的MMX,SSE,都是指令集的一種。使用軟件可以查詢不同cpu支持的指令集,比如下面一張圖:

可以看到i5處理器已經(jīng)支持了很多的指令集。
1.2 執(zhí)行過程
CPU的基本工作是執(zhí)行存儲的指令序列,即程序。程序的執(zhí)行過程實際上是不斷地取出指令、分析指令、執(zhí)行指令的過程。幾乎所有的馮?諾伊曼型計算機的CPU,其工作都可以分為5個階段:取指令、指令譯碼、執(zhí)行指令、訪存取數(shù)和結(jié)果寫回。
我們可以簡單理解為,cpu在控制器,存儲器,數(shù)據(jù)總線等多種部件的協(xié)調(diào)下,以一種流水線的方式取出要執(zhí)行的二級制代碼序列,使用內(nèi)部的指令集來理解并執(zhí)行每一條指令。這其中又會涉及到指令周期,時鐘周期,cpu主頻等概念。一個cpu的內(nèi)部結(jié)構(gòu)圖大概如下圖所示:

2. x86匯編和二進制機器碼
按照前面我們所說,不同的cpu支持不用的指令集(其實這里的概念應(yīng)該從架構(gòu)上來說)。也就是說,不同的cpu架構(gòu)其實存在不同的匯編語言。在pc上廣泛使用的cpu架構(gòu)和匯編是intel公司的80x86系列和對應(yīng)的x86匯編。
匯編指令可以通過匯編編譯器翻譯成對應(yīng)的二進制指令,進而由cpu直接執(zhí)行。匯編指令和二進制機器碼直接對應(yīng),可以通過查閱intel的cpu技術(shù)文檔了解這種對應(yīng)關(guān)系的具體細(xì)節(jié)。
3. 寄存器的概念和x86 cpu中的寄存器
關(guān)于寄存器的基本概念,百度百科是這樣解釋的
在計算機領(lǐng)域,寄存器是CPU內(nèi)部的元件,包括通用寄存器、專用寄存器和控制寄存器。寄存器擁有非常高的讀寫速度,所以在寄存器之間的數(shù)據(jù)傳送非常快。
寄存器是內(nèi)存階層中的最頂端,也是系統(tǒng)獲得操作資料的最快速途徑。
簡單點理解,寄存器是最高速的內(nèi)存單元,與cpu直連,擁有最快的訪問和存取速度。我們一般意義上的內(nèi)存,比之寄存器,速度上就沒得比了。寄存器的意義在于,為cpu提供了一種快速速度存取途徑,加速了cpu的運行速度。
32位CPU所含有的寄存器如下:
4個數(shù)據(jù)寄存器(EAX、EBX、ECX和EDX)
2個變址和指針寄存器(ESI和EDI)
2個指針寄存器(ESP和EBP)
6個段寄存器(ES、CS、SS、DS、FS和GS)
1個指令指針寄存器(EIP)
1個標(biāo)志寄存器(EFlags)
這些寄存器的作用,在此不做詳細(xì)解釋。在x86匯編中,我們會直接使用這些寄存器來進行運算。因為本篇并不是一個x86匯編的教學(xué)帖,我們會在后面的講解中對用到的寄存器做一些補充說明。
結(jié)束語
本篇在此打住,也許各位看官仍然有很多不理解的部分,因為本篇的介紹實在是有些過于簡單。但是相信我,我們的主題從來都不是機器碼,二進制,匯編。我們會在后續(xù)的章節(jié)中,探究一些關(guān)于C++語言層面的問題,又或者是一些代碼安全問題。我會努力把更多精彩的文章帶給大家,我們拭目以待。