日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > C語言與CPP編程
[導讀]CPU對我們來說既熟悉又陌生,熟悉的是我們知道代碼是被CPU執(zhí)行的,當我們的線上服務出現問題時可能首先會查看CPU負載情況。陌生的是我們并不知道CPU是如何執(zhí)行代碼的,它對我們的代碼做了什么。本文意在簡單解釋我們代碼的生命周期,以及代碼是如何在CPU上跑起來的。編譯-讓計算機認識...

CPU對我們來說既熟悉又陌生,熟悉的是我們知道代碼是被CPU執(zhí)行的,當我們的線上服務出現問題時可能首先會查看CPU負載情況。陌生的是我們并不知道CPU是如何執(zhí)行代碼的,它對我們的代碼做了什么。本文意在簡單解釋我們代碼的生命周期,以及代碼是如何在CPU上跑起來的。


編譯-讓計算機認識我

一個漂亮 control c 加上一個漂亮的 control v,啪~,我們愉快的寫下了代碼,當代碼被保存后,它就被存在我們磁盤的某個地方,它可能是像java或者python這些高級語言寫的,也可能是像c這種古老語言寫的,但是現在它肯定沒法被運行,因為計算機不認識它們,計算機只認識0、1這樣的二進制,簡稱機器碼,那為什么我們不直接寫機器碼?如果你有這樣的思考,我只能呵呵了,請你幫我翻譯下以下機器碼:


001010100101001001001
100100101000101010101
很明顯作為高質量人類的我們也無法識別出這段代碼寫的是什么,于是出現類似java這樣的高級語言,它們給機器碼穿上了一層外衣,然后交給偉大的程序員來創(chuàng)造未來。

所以反過來我們的代碼需要被替換成機器碼,這樣才能被計算機認識,計算機才能幫我們干事。這個轉換的過程我們通常叫「編譯」。


#include
int main()
{
printf("Hello World\n");
return 0;
}
這是一段應該每個程序員都寫過的代碼(hello.c),在Linux下,當我們使用GCC來編譯Hello World程序時,只需要最簡單的命令:

gcc hello.c
./hello
# Hello World
看似很簡單的一行,但是其實編譯的過程很復雜,并不是我們想象中的編譯,真實是分為4個步驟,分別是預處理(Prepressing)、編譯(Compliation)、匯編(Assertmbly)和鏈接(Linking)。

  • 預編譯:這個過程主要是處理源代碼中以“#”開始的預編譯指令,比如“#include”、“define”等。
  • 編譯:這個過程就是把預處理完的文件進行詞法分析、語法分析、語義分析及優(yōu)化后生產成相應的匯編代碼,這個過程是最復雜的。
  • 匯編:這個過程就是將匯編代碼轉換成機器碼,也就是上圖的目標文件hello.o
  • 鏈接:我們的代碼程序經常是由多個代碼文件組成的,當每個文件都被匯編成“.o”文件時,需要一套機制將它們「組裝」在一起,這個過程就叫做鏈接。
  • 好吧,原來編譯是這么回事,通過這一整套的編譯操作,我們代碼終于能執(zhí)行了,我們簡簡單單的運行

    ./hello.out即可輸出Hello World。等等,這個簡簡單單的過程發(fā)生了什么?

    連接-中轉站和高速公路

    ok,ok,通過編譯,我們的程序終于能執(zhí)行了,接下來讓我們站在CPU的視角來看看Hello World是如何被打印出來的。


    首先編譯好的文件是存在磁盤上的,得先加載到內存中,這里你可能會問:為什么CPU不能直接讀取磁盤的程序運行而要經過內存?答案是慢,緩慢的磁盤會影響我們程序執(zhí)行的速度,因此需要更加快速、離CPU更近的存儲,那就是內存。


    內存是一大塊存儲空間,可以存儲很多數據信息,那么如何找到我們要寫的程序呢?答案是地址,其實每個字節(jié)在內存中都有一個地址,這樣當CPU去內存中讀我們的程序時,只需要根據對應的地址就可以知道我們程序的具體內容。


    等等...,這里似乎又有個問題,CPU是如何與我們的內存、磁盤通信的?應該有個媒介之類的吧。沒錯,這個媒介就是主板上的總線芯片組,總線好理解,就像高速公路,數據信息可以通過這條高速公路傳遞到CPU中,這個芯片組是個什么玩意?電腦主板上芯片很多,這里說的主要是南橋芯片和北橋芯片。先來個解釋:


  • 北橋芯片:北橋負責高速設備和CPU之間的溝通,主要就是CPU和內存、顯卡之間的通信,但是隨著技術的迭代,主板上的北橋芯片已經被內置到了CPU里了。
  • 南橋芯片:南橋負責低速設備和北橋之間的通信,主要負責I/O總線之間的通信,如USB、LAN、ATA、SATA、音頻控制器、鍵盤控制器、實時時鐘控制器、高級電源管理等。
  • 嗯... 為什么CPU與高速設備、低速設備之間的通信需要這兩個芯片?CPU自己不能干嗎?這里還是類似拆分任務的功能,如果把所有的任務都交給CPU來處理,CPU會太忙了,還有比較重要的一點,如果南橋芯片壞了,那么我們可以直接更換南橋,而不用換掉整個CPU。


    終于CPU通過總線和芯片打通了磁盤、內存之間的通信了,接下來的一切開始交給CPU。


    CPU-最強大腦

    CPU全稱是Central Processing Unit,即中央處理單元,它的本質就是一塊超大規(guī)模的集成電路。從邏輯上來分,它的內部是由寄存器、控制器、運算器和時鐘組成的,下面來解釋下各個組成是干什么的。


    • 寄存器:CPU內部其實有很多類型的寄存器,我們只需了解寄存器就是暫存數據、指令等信息的,它的本質是臨時存儲,由于是直接集成在CPU內部,所以讀寫它們的速度很快,一般一個CPU內部會有20-100個寄存器,這里給大家列舉下常用寄存器與其功能。


    • 累加寄存器:存儲執(zhí)行運算的數據和運算后的數據
    • 標志寄存器:存儲運算處理后的CPU的狀態(tài)
    • 程序計數器:存儲下一條指令所在內存的地址
    • 基址寄存器:存儲數據內存的起始地址
    • 變址寄存器:存儲基址寄存器的相對地址
    • 通用寄存器:存儲任意數據
    • 指令寄存器:存儲指令,CPU內部使用,程序員無法通過程序對該寄存器進行讀寫操作
    • 棧寄存器:存儲棧區(qū)域的起始地址
    • 控制器:控制器負責把數據讀出或者寫入寄存器,并根據指令的結果來控制計算機。


    • 運算器:從名字就可以猜出來,運算器的主要工作就是運算,運算從內存讀入寄存器的值


    • 時鐘:它并不是我們見的鐘表概念,它代表了你的CPU的工作頻率,頻率越高說明你的CPU處理的速度越快,但是越快就會帶來另一個問題:散熱。


    綜上所述,CPU的大致工作流程如下:在時鐘信號到來的時候,就開始工作,通過控制器把內存的數據讀到各個寄存器中,然后如果有計算相關的邏輯,就交給運算器。發(fā)現沒有,CPU的工作其實挺簡單的,本質就是不停的讀指令、執(zhí)行指令。但是CPU是如何讀到我們的代碼指令的,以及我們的代碼里面的if else、函數調用都是如何執(zhí)行分支判斷、函數跳轉的,我們來看個例子:


    a = 1 #0x0010
    b = 2 #0x0011
    if a > b { #0x0012
    printf("%s","a") #0x0013
    } else {
    add(a,b) #0x0014
    }
    printf("%s","end") #0x0017

    func add(int a,int b) { #0x0020
    return a b
    }
    這是段非常簡單的偽代碼,有分支判斷、有函數跳轉。我們來從CPU的角度看看它是如何執(zhí)行的:

  • 首先每段程序都有個開始的地址0x0010,也就是CPU讀取程序的入口
  • 把a=1這個數字讀入通用寄存器中,程序計數器(PC寄存器)自動加1,即指向下一條指令 0x0011
  • 指令寄存器拿到程序計數器的指令地址,把b=2這個數字讀入通用寄存器中,程序計數器(PC寄存器)自動加1,即指向下一條指令0x0012
  • 指令寄存器發(fā)現此處是比較邏輯,會執(zhí)行a-b,此時可能會有三個結果分別是大于0,等于0,小于0,然后把這個結果存到標志寄存器里,這里有個小知識,我們經常說的是CPU是64位或者32位,其實也表示了標志寄存器的長度
  • 很明顯,a是小于b的,CPU根據標志寄存器的狀態(tài)值應該跳轉到else里面,注意這時程序計數器的值不是加1,而是設置成else的地址 0x0014,當執(zhí)行到0x0015的時候,需要發(fā)生函數跳轉,程序計數器會被設置成 0x0020,但是這里并不是簡單的函數跳轉(專業(yè)術語叫做call),因為在函數執(zhí)行完畢之后,還要返回,也就是程序計數器需要從0x0020再變成0x0017。call執(zhí)行的時候會把后續(xù)要執(zhí)行的指令地址0x0017存到中。
  • 當我們的add函數執(zhí)行完畢之后,會有個return,return的時候會把上一步驟存入棧中的地址0x0017寫入程序計數器中
  • 指令寄存器根據程序計數器當前的地址執(zhí)行最后的打?。╡nd),結束。
  • 順序執(zhí)行的指令代碼,程序計數器會自動累加(當然不一定累加的是1),然后找到下一條要執(zhí)行的指令。


    分支判斷的時候,程序計數器不是簡單的累加地址,需要地址的跳轉。


    函數調用不僅僅需要跳轉地址,還要把函數執(zhí)行完畢之后要執(zhí)行的地址存下來,方便折回繼續(xù)執(zhí)行。


    其實還有個循環(huán)執(zhí)行,也就是我們代碼中的for、while之類的,這時程序計數器會不停的在某些地址之間來回切換。



    本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯系該專欄作者,如若文章內容侵犯您的權益,請及時聯系本站刪除。
    換一批
    延伸閱讀

    LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

    關鍵字: 驅動電源

    在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅動性能的關鍵。

    關鍵字: 工業(yè)電機 驅動電源

    LED 驅動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

    關鍵字: 驅動電源 照明系統(tǒng) 散熱

    根據LED驅動電源的公式,電感內電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

    關鍵字: LED 設計 驅動電源

    電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

    關鍵字: 電動汽車 新能源 驅動電源

    在現代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質量和效率直接關系到城市的公共安全、居民生活質量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

    關鍵字: 發(fā)光二極管 驅動電源 LED

    LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數校正(PFC)、空間受限和可靠性等。

    關鍵字: LED 驅動電源 功率因數校正

    在LED照明技術日益普及的今天,LED驅動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

    關鍵字: LED照明技術 電磁干擾 驅動電源

    開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現在的LED驅動電源

    關鍵字: LED 驅動電源 開關電源

    LED驅動電源是把電源供應轉換為特定的電壓電流以驅動LED發(fā)光的電壓轉換器,通常情況下:LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

    關鍵字: LED 隧道燈 驅動電源
    關閉