<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          沒錯!cxuan 對匯編下手了

          共 5762字,需瀏覽 12分鐘

           ·

          2021-09-18 19:05


          匯編代碼是計算機(jī)的一種低級表示,它是一種低級語言,可以從字面角度去理解它,包括處理數(shù)據(jù)、管理內(nèi)存、讀寫存儲設(shè)備上的數(shù)據(jù),以及利用網(wǎng)絡(luò)通信等。編譯器生成機(jī)器碼經(jīng)過了一系列的轉(zhuǎn)換,這些轉(zhuǎn)換遵循編程語言、目標(biāo)機(jī)器的指令集操作系統(tǒng)

          指令集

          指令集就是指揮計算機(jī)工作的指令,因為程序就是按照一定執(zhí)行順序排列的指令。因為計算機(jī)的執(zhí)行控制權(quán)由 CPU 操作,所以指令集就是 CPU 中用來計算和控制計算機(jī)的一系列指令的集合。每個 CPU 在產(chǎn)出時都規(guī)定了與硬件電路相互配合工作的指令集。

          指令集有不少分類,但是一般分為兩種,一種是精簡指令集,一種是復(fù)雜指令集。具體描述如下

          精簡指令集

          精簡指令的英文是 reduced instruction set computer, RISC,原意是精簡指令集計算,簡稱為精簡指令集,是 CPU 的一種 設(shè)計模式,可以把 CPU 想象成一家流水線工廠,對指令數(shù)目尋址方式都做了精簡,使其實現(xiàn)更容易,指令并行執(zhí)行程度更好,編譯器的效率更高。

          常見的精簡指令集處理器包括 ARM、AVR、MIPS、PARISC、RISC-V 和 SPARC。

          所以你就能理解

          這本書是講啥的了。

          它主要是基于 MIPS 體系結(jié)構(gòu)把馮諾依曼體系的五大組件進(jìn)行了逐一的硬件實現(xiàn) + 軟件設(shè)計介紹,更為重要的是引入了諸多并行計算的內(nèi)容,這是大部分教材中忽略或者內(nèi)容較少的,會根據(jù)這個思路把并行相關(guān)的內(nèi)容,結(jié)合 OpenMP, CUDA 和 Hadoop/Spark 整體融入到新書中,畢竟這是未來發(fā)展的趨勢

          還有這本書

          這本書又是講啥的。

          這本書是講 RISC-V 指令集的,因為指令集的不同也區(qū)分了三個版本,三個版本???嗯,還有下面這個

          這本書是講 ARM 指令集的。

          所以一般在看 CASPP 的時候并發(fā)的看看這本書是非常不錯的選擇。

          精簡指令集一般具有如下特征

          • 統(tǒng)一的指令編碼
          • 通用的寄存器,一般會區(qū)分整數(shù)和浮點數(shù)
          • 簡單的尋址模式,復(fù)雜尋址模式被簡單指令序列來取代
          • 支持很少偏門的類型,例如 RISC 支持字節(jié)字符串類型。

          復(fù)雜指令集

          復(fù)雜指令集的英文是 Complex Instruction Set Computing, CISC,是一種微處理器指令集架構(gòu),也被譯為復(fù)雜指令集。

          復(fù)雜指令集包括 System/360、VAX、x86 等。

          復(fù)雜指令集可以說是在精簡指令集之上作出的改變。

          復(fù)雜指令集的特點是指令數(shù)目多而復(fù)雜,每條指令字長并不相等,計算機(jī)必須加以判讀,并為此付出了性能的代價。

          一般來說,提升 CPU 性能的方法有如下這幾種

          • 增加寄存器的大小
          • 增進(jìn)內(nèi)部的并行性
          • 增加高速緩存的大小
          • 增加核心時脈的速度
          • 加入其他功能,例如 IO 和計時器
          • 加入向量處理器
          • 硬件多線程技術(shù)

          比較抽象,我們后面會組織成文章具體介紹一下。

          C 編譯器會接收其他操作并把其轉(zhuǎn)換為匯編語言輸出,匯編語言是機(jī)器級別的代碼表示。我們之前介紹過,C 語言程序的執(zhí)行過程分為下面這幾步

          下面我們更多的討論都是基于匯編代碼來討論。

          我們?nèi)粘K佑|的高級語言,都是經(jīng)過了層層封裝的結(jié)果,所以我們平常是接觸不到匯編語言的,更不會用匯編語言來進(jìn)行編程,這就和你不知道操作系統(tǒng)的存在一樣,但其實你每個操作,甚至你雙擊一個圖標(biāo)都和操作系統(tǒng)有關(guān)系。

          高級語言的抽象級別很高,但是經(jīng)過了層層抽象之后,高級語言的執(zhí)行效率肯定沒有匯編語言高,也沒有匯編語言可靠。

          但是高級語言有更大的優(yōu)點是其編譯后能夠在不同的機(jī)器上運行,匯編語言針對不同的指令集有不同的表示。并且高級語言學(xué)習(xí)來更加通俗易懂,降低計算機(jī)門檻,讓內(nèi)卷更加嚴(yán)重(當(dāng)然這是開個玩笑,冒犯到請別當(dāng)真)。

          話不多說,了解底層必須了解匯編語言。否則一個 synchronized 底層實現(xiàn)就能夠讓你頭疼不已。而且,天天飄著也不好,遲早要落地。

          了解匯編代碼也有助于我們優(yōu)化程序代碼,分析代碼中隱含的低效率,并且這種優(yōu)化方法一旦優(yōu)化成功,將是量級的提高,而不是改改 if...else ,使用一個新特性所能比的。

          機(jī)器級代碼

          計算機(jī)系統(tǒng)使用了多種不同形式的抽象,可以通過一個簡單的抽象模型來隱藏實現(xiàn)細(xì)節(jié)。對于機(jī)器級別的程序來說,有兩點非常重要。

          首先第一點,定義機(jī)器級別程序的格式和行為被稱為 指令集體系結(jié)構(gòu)或指令集架構(gòu)(instruction set architecture), ISA。ISA 定義了進(jìn)程狀態(tài)、指令的格式和每一個指令對狀態(tài)的影響。大部分的指令集架構(gòu)包括 ISA 用來描述進(jìn)程的行為就好像是順序執(zhí)行的,一條指令執(zhí)行結(jié)束后,另外一條指令再開始。處理器硬件的描述要更復(fù)雜,它可以同時并行執(zhí)行許多指令,但是它采用了安全措施來確保整體行為與 ISA 規(guī)定的順序一致。

          第二點,機(jī)器級別對內(nèi)存地址的描述就是 虛擬地址(virtual address),它提供了一個內(nèi)存模型來表示一個巨大的字節(jié)數(shù)組。

          編譯器在整個編譯的過程中起到了至關(guān)重要的作用,把 C 語言轉(zhuǎn)換為處理器執(zhí)行的基本指令。匯編代碼非常接近于機(jī)器代碼,只不過與二進(jìn)制機(jī)器代碼相比,匯編代碼的可讀性更強(qiáng),所以理解匯編是理解機(jī)器工作的第一步。

          一些進(jìn)程狀態(tài)對機(jī)器可見,但是 C 語言程序員卻看不到這些,包括

          • 程序計數(shù)器(Program counter),它存儲下一條指令的地址,在 x86-64 架構(gòu)中用 %rip 來表示。

          程序執(zhí)行時,PC 的初始值為程序第一條指令的地址,在順序執(zhí)行程序時, CPU 首先按程序計數(shù)器所指出的指令地址從內(nèi)存中取出一條指令,然后分析和執(zhí)行該指令,同時將 PC 的值加 1 并指向下一條要執(zhí)行的指令。

          比如下面一個例子。

          這是一段數(shù)值進(jìn)行相加的操作,程序啟動,在經(jīng)過編譯解析后會由操作系統(tǒng)把硬盤中的程序復(fù)制到內(nèi)存中,示例中的程序是將 123 和 456 執(zhí)行相加操作,并將結(jié)果輸出到顯示器上。由于使用機(jī)器語言難以描述,所以這是經(jīng)過翻譯后的結(jié)果,實際上每個指令和數(shù)據(jù)都可能分布在不同的地址上,但為了方便說明,把組成一條指令的內(nèi)存和數(shù)據(jù)放在了一個內(nèi)存地址上。

          • 整數(shù)寄存器文件(register file)包含 16 個命名的位置,用來存儲 64 位的值。這些寄存器可以存儲地址和整型數(shù)據(jù)。有些寄存器用于跟蹤程序狀態(tài),而另一些寄存器用于保存臨時數(shù)據(jù),例如過程的參數(shù)和局部變量,以及函數(shù)要返回的值。這個 文件 是和磁盤文件無關(guān)的,它只是 CPU 內(nèi)部的一塊高速存儲單元。有專用的寄存器,也有通用的寄存器用來存儲操作數(shù)。
          • 條件碼寄存器 用來保存有關(guān)最近執(zhí)行的算術(shù)或邏輯指令的狀態(tài)信息。這些用于實現(xiàn)控件或數(shù)據(jù)流中的條件更改,例如實現(xiàn) if 和 while 語句所需的條件更改。我們都學(xué)過高級語言,高級語言中的條件控制流程主要分為三種:順序執(zhí)行、條件分支、循環(huán)判斷三種,順序執(zhí)行是按照地址的內(nèi)容順序的執(zhí)行指令。條件分支是根據(jù)條件執(zhí)行任意地址的指令。循環(huán)是重復(fù)執(zhí)行同一地址的指令。
            • 順序執(zhí)行的情況比較簡單,每執(zhí)行一條指令程序計數(shù)器的值就是 + 1。
            • 條件和循環(huán)分支會使程序計數(shù)器的值指向任意的地址,這樣一來,程序便可以返回到上一個地址來重復(fù)執(zhí)行同一個指令,或者跳轉(zhuǎn)到任意指令。

          下面以條件分支為例來說明程序的執(zhí)行過程(循環(huán)也很相似)

          程序的開始過程和順序流程是一樣的,CPU 從 0100 處開始執(zhí)行命令,在 0100 和 0101 都是順序執(zhí)行,PC 的值順序+1,執(zhí)行到 0102 地址的指令時,判斷 0106 寄存器的數(shù)值大于 0,跳轉(zhuǎn)(jump)到 0104 地址的指令,將數(shù)值輸出到顯示器中,然后結(jié)束程序,0103 的指令被跳過了,這就和我們程序中的 if() 判斷是一樣的,在不滿足條件的情況下,指令會直接跳過。所以 PC 的執(zhí)行過程也就沒有直接+1,而是下一條指令的地址。

          • 一組 向量寄存器用來存儲一個或者多個整數(shù)或者浮點數(shù)值,向量寄存器是對一維數(shù)據(jù)上進(jìn)行操作。

          機(jī)器指令只會執(zhí)行非常簡單的操作,例如將存放在寄存器的兩個數(shù)進(jìn)行相加,把數(shù)據(jù)從內(nèi)存轉(zhuǎn)移到寄存器中或者是條件分支轉(zhuǎn)移到新的指令地址。編譯器必須生成此類指令的序列,以實現(xiàn)程序構(gòu)造,例如算術(shù)表達(dá)式求值,循環(huán)或過程調(diào)用和返回

          認(rèn)識匯編

          我相信各位應(yīng)該都知道匯編語言的出現(xiàn)背景吧,那就是二進(jìn)制表示數(shù)據(jù),太復(fù)雜太龐大了,為了解決這個問題,出現(xiàn)了匯編語言,匯編語言和機(jī)器指令的區(qū)別就在于表示方法上,匯編使用操作數(shù)來表示,機(jī)器指令使用二進(jìn)制來表示,我之前多次提到機(jī)器碼就是匯編,你也不能說我錯,但是不準(zhǔn)確。

          但是匯編適合二進(jìn)制代碼存在轉(zhuǎn)換關(guān)系的。

          匯編代碼需要經(jīng)過 匯編器 編譯后才產(chǎn)生二進(jìn)制代碼,這個二進(jìn)制代碼就是目標(biāo)代碼,然后由鏈接器將其連接起來運行。

          匯編語言主要分為以下三類

          • 匯編指令:它是一種機(jī)器碼的助記符,它有對應(yīng)的機(jī)器碼
          • 偽指令:沒有對應(yīng)的機(jī)器碼,由編譯器執(zhí)行,計算機(jī)并不執(zhí)行
          • 其他符號,比如 +、-、*、/ 等,由編譯器識別,沒有對應(yīng)的機(jī)器碼

          匯編語言的核心是匯編指令,而我們對匯編的探討也是基于匯編指令展開的。

          與匯編有關(guān)的硬件和概念

          CPU

          CPU 是計算機(jī)的大腦,它也是整個計算機(jī)的核心,它也是執(zhí)行匯編語言的硬件,CPU 的內(nèi)部包含有寄存器,而寄存器是用于存儲指令和數(shù)據(jù)的,匯編語言的本質(zhì)也就是 CPU 內(nèi)部操作數(shù)所執(zhí)行的一系列計算。

          內(nèi)存

          沒有內(nèi)存,計算機(jī)就像是一個沒有記憶的人類,只會永無休止的重復(fù)性勞動。CPU 所需的指令和數(shù)據(jù)都由內(nèi)存來提供,CPU 指令經(jīng)由內(nèi)存提供,經(jīng)過一系列計算后再輸出到內(nèi)存。

          磁盤

          磁盤也是一種存儲設(shè)備,它和內(nèi)存的最大區(qū)別在于永久存儲,程序需要在內(nèi)存裝載后才能運行,而提供給內(nèi)存的程序都是由磁盤存儲的。

          總線

          一般來說,內(nèi)存內(nèi)部會劃分多個存儲單元,存儲單元用來存儲指令和數(shù)據(jù),就像是房子一樣,存儲單元就是房子的門牌號。而 CPU 與內(nèi)存之間的交互是通過地址總線來進(jìn)行的,總線從邏輯上分為三種

          • 地址線
          • 數(shù)據(jù)線
          • 控制線

          • CPU 與存儲器之間的讀寫主要經(jīng)過以下幾步


          讀操作步驟

          • CPU 通過地址線發(fā)出需要讀取指令的位置
          • CPU 通過控制線發(fā)出讀指令
          • 內(nèi)存把數(shù)據(jù)放在數(shù)據(jù)線上返回給 CPU

          寫操作步驟

          • CPU 通過地址線發(fā)出需要寫出指令的位置
          • CPU 通過控制線發(fā)出寫指令
          • CPU 把數(shù)據(jù)通過數(shù)據(jù)線寫入內(nèi)存

          下面我們就來具體了解一下這三類總線

          地址總線

          通過我們上面的探討,我們知道 CPU 通過地址總線來指定存儲位置的,地址總線上能傳送多少不同的信息,CPU 就可以對多少個存儲單元進(jìn)行尋址。

          上圖中 CPU 和內(nèi)存中間信息交換通過了 10 條地址總線,每一條線能夠傳遞的數(shù)據(jù)都是 0 或 1 ,所以上圖一次 CPU 和內(nèi)存?zhèn)鬟f的數(shù)據(jù)是 2 的十次方。

          所以,如果 CPU 有 N 條地址總線,那么可以說這個地址總線的寬度是 N 。這樣 CPU 可以尋找 2 的 N 次方個內(nèi)存單元。

          數(shù)據(jù)總線

          CPU 與內(nèi)存或其他部件之間的數(shù)據(jù)傳送是由數(shù)據(jù)總線來完成的。數(shù)據(jù)總線的寬度決定了 CPU 和外界的數(shù)據(jù)傳輸速度。8 根數(shù)據(jù)總線可以一次傳送一個 8 位二進(jìn)制數(shù)據(jù)(即一個字節(jié))。16 根數(shù)據(jù)總線一次可以傳輸兩個字節(jié),32 根數(shù)據(jù)總線可以一次傳輸四個字節(jié)。。。。。。

          控制總線

          CPU 與其他部件之間的控制是通過 控制總線 來完成的。有多少根控制總線,就意味著 CPU 提供了對外部器件的多少種控制。所以,控制總線的寬度決定了 CPU 對外部部件的控制能力。

          一次內(nèi)存的讀取過程

          內(nèi)存結(jié)構(gòu)

          內(nèi)存 IC 是一個完整的結(jié)構(gòu),它內(nèi)部也有電源、地址信號、數(shù)據(jù)信號、控制信號和用于尋址的 IC 引腳來進(jìn)行數(shù)據(jù)的讀寫。下面是一個虛擬的 IC 引腳示意圖

          圖中 VCC 和 GND 表示電源,A0 - A9 是地址信號的引腳,D0 - D7 表示的是控制信號、RD 和 WR 都是好控制信號,我用不同的顏色進(jìn)行了區(qū)分,將電源連接到 VCC 和 GND 后,就可以對其他引腳傳遞 0 和 1 的信號,大多數(shù)情況下,+5V 表示1,0V 表示 0。

          我們都知道內(nèi)存是用來存儲數(shù)據(jù),那么這個內(nèi)存 IC 中能存儲多少數(shù)據(jù)呢?D0 - D7 表示的是數(shù)據(jù)信號,也就是說,一次可以輸入輸出 8 bit = 1 byte 的數(shù)據(jù)。A0 - A9 是地址信號共十個,表示可以指定 00000 00000 - 11111 11111 共 2 的 10次方 = 1024個地址。每個地址都會存放 1 byte 的數(shù)據(jù),因此我們可以得出內(nèi)存 IC 的容量就是 1 KB。

          如果我們使用的是 512 MB 的內(nèi)存,這就相當(dāng)于是 512000(512 * 1000) 個內(nèi)存 IC。當(dāng)然,一臺計算機(jī)不太可能有這么多個內(nèi)存 IC ,然而,通常情況下,一個內(nèi)存 IC 會有更多的引腳,也就能存儲更多數(shù)據(jù)。

          內(nèi)存讀取過程

          下面是一次內(nèi)存的讀取過程。

          來詳細(xì)描述一下這個過程,假設(shè)我們要向內(nèi)存 IC 中寫入 1byte 的數(shù)據(jù)的話,它的過程是這樣的:

          • 首先給 VCC 接通 +5V 的電源,給 GND 接通 0V 的電源,使用 A0 - A9 來指定數(shù)據(jù)的存儲場所,然后再把數(shù)據(jù)的值輸入給 D0 - D7 的數(shù)據(jù)信號,并把 WR(write)的值置為 1,執(zhí)行完這些操作后,即可以向內(nèi)存 IC 寫入數(shù)據(jù)
          • 讀出數(shù)據(jù)時,只需要通過 A0 - A9 的地址信號指定數(shù)據(jù)的存儲場所,然后再將 RD 的值置為 1 即可。
          • 圖中的 RD 和 WR 又被稱為控制信號。其中當(dāng)WR 和 RD 都為 0 時,無法進(jìn)行寫入和讀取操作。

          總結(jié)

          此篇文章我們主要探討了指令集、指令集的分類,與匯編有關(guān)的硬件,總線都有哪些,分別的作用都是什么,然后我們以一次內(nèi)存讀取過程來連接一下 CPU 和內(nèi)存的交互過程。

          原創(chuàng)不易,如有幫助還請各位讀者四連(點在、在看、分享、留言),感謝各位大佬





           往期推薦 

          ??

          HTTP 2.0 ,有點炸 !

          從 0 到 100

          這篇 Java 基礎(chǔ),我吹不動了

          程序員有未來嗎?

          這篇零拷貝,牛了牛了

          JVM 基礎(chǔ)面試題總結(jié)


          瀏覽 26
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美黄色一级片免费看 | 做爱www| 亚洲成人网站无码在线观看 | 农村一级婬片A片AAA毛片古装 | 亚洲精品字幕 |