計算機組成原理-指令和運算

計算機組成原理-指令和運算

  本文根據徐文浩老師的計算機組成原理記錄:計算機組成原理

  CSDN base64 圖片顯示有問題, 想要個人筆記的可以私我

1 計算機指令

  計算機指令集,英文叫 Instruction Set。這裏面的“Set”,其實就是數學上的集合,代表不同的單詞、語法。

  要讓一段程序在一個 Linux 操作系統上跑起來,我們需要把整個程序翻譯成一個彙編語言(ASM,Assembly Language)的程序,這個過程我們一般叫編譯(Compile)成彙編代碼。

  針對彙編代碼,我們可以再用匯編器(Assembler)翻譯成機器碼(Machine Code)。這些機器碼由“0”和“1”組成的機器語言表示。這一條條機器碼,就是一條條的計算機指令。這樣一串串的 16 進制數字,就是我們 CPU 能夠真正認識的計算機指令。

![編譯彙編][編譯彙編]

  C語言>彙編語言>機器語言 一般是這樣的編譯順序,爲什麼不是 C語言>機器語言 一步到位這樣編譯呢?

  其實有一步到位的,就是兩個步驟都通過一個命令先後執行,順序完成,gcc現在就可以一個命令直接變成可執行的binary。只是爲了方便debug,你可以認爲通過機器語言我們也可以反推出彙編語言長什麼樣子。

  在Linux 操作系統上,可以簡單地使用 gcc 和 objdump 這樣兩條命令,把對應的彙編代碼和機器碼都打印出來。

$ gcc -g -c test.c
$ objdump -d -M intel -S test.o

1.1 常見 的解析指令和機器碼

編號 指令類型 說明 示例命令 示例彙編代碼 含義 註釋
1 算術類指令 加減乘除,在 CPU 層面,都會變成一條條算術類指令 add add $s1,$s2,$s3 $s1=$s2+$s3 將 s2 和 s3 寄存器中的數相加後的結果放到寄存器 s1 中
2 邏輯類指令 邏輯上的與或非 or or $s1,$s2,$s3 $s1=$s2 | $s3 將 s2 和 s3 寄存器中的數按位取或後的結果放到寄存器 s1 中
3 數據傳輸指令 給變量賦值、在內存裏讀寫數據,用的都是數據傳輸類指令 load word load $s1,10($s2) $s1=memory($s2+10) 取 s2 寄存器中的數,加上10偏移量後,找到內存中的字,存入到s1寄存器中
4 條件分支類指令 "if/else"之類的指令 branch on equal beq $s1,$s210 if($s1 == $s2) go to PC+4+10 如果 s1 和 s2 寄存器內的值相等,從程序計數器往後跳10
5 無條件跳轉指令 調用函數的時候,就是發起了一個無條件跳轉指令 jump j 1000 go to 1000 跳轉到 1000 這個目標地址

2 寄存器

  一個 CPU 有多個寄存器, 每個寄存器都有各自的名字; 如 64 位處理器,有 16 個寄存器(RAX、RBX、RCX、RDX、RSI、RDI、RBP、RSP、CS、DS、ES、SS、FS、GS、RIP、RFLAGS)

  三個特殊的寄存器:

![特殊的寄存器][特殊的寄存器]

3 鏈接

  Linux 和 Windows 中的鏈接各式不同, linux 下爲 ELF 格式, Windows 下爲 PE 格式;

  如果我們有一個可以能夠解析 PE 格式的裝載器,我們就有可能在 Linux 下運行 Windows 程序了。這樣的程序真的存在嗎?沒錯,Linux 下著名的開源項目 Wine,就是通過兼容 PE 格式的裝載器,使得我們能直接在 Linux 下運行 Windows 程序的。而現在微軟的 Windows 裏面也提供了 WSL,也就是 Windows Subsystem for Linux,可以解析和加載 ELF 格式的文件

3.1 ELF 鏈接

   ELF(Execuatable and Linkable File Format) 中文名字叫可執行與可鏈接文件格式,這裏面不僅存放了編譯成的彙編指令,還保留了很多別的數據

![ELF文件格式信息][ELF文件格式信息]

3.2 PE 鏈接

  Windows 的可執行文件格式是一種叫作PE(Portable Executable Format)的文件格式

4 程序裝載

  在運行這些可執行文件的時候,其實是通過一個裝載器,解析 ELF 或者 PE 格式的可執行文件。裝載器會把對應的指令和數據加載到內存裏面來,讓 CPU 去執行

  實際上裝載器需要滿足兩個要求:

  1. 可執行程序加載後佔用的內存空間應該是連續的。執行指令的時候,程序計數器是順序地一條一條指令執行下去。這也就意味着,這一條條指令需要連續地存儲在一起
  2. 正常情況下需要同時加載很多個程序,並且不能讓程序自己規定在內存中加載的位置。雖然編譯出來的指令裏已經有了對應的各種各樣的內存地址,但是實際加載的時候,其實沒有辦法確保,這個程序一定加載在哪一段內存地址上。因爲現在的計算機通常會同時運行很多個程序,可能你想要的內存地址已經被其他加載了的程序佔用了

4.1 虛擬內存地址

  爲了滿足這兩個基本要求, 可以在內存裏面,找到一段連續的內存空間,然後分配給裝載的程序,然後把這段連續的內存空間地址,和整個程序指令裏指定的內存地址做一個映射

  指令裏用到的內存地址叫作虛擬內存地址(Virtual Memory Address),實際在內存硬件裏面的空間地址,我們叫物理內存地址(Physical Memory Address)

4.2 內存分段和內存交換

  找出一段連續的物理內存和虛擬內存地址進行映射的方法,我們叫分段(Segmentation)。這裏的段,就是指系統分配出來的那個連續的內存空間。

![內存碎片][內存碎片]

  內存碎片的解決方式: 內存交換

4.3 內存分頁

  虛擬內存、分段,再加上內存交換,看起來似乎已經解決了計算機同時裝載運行很多個程序的問題。不過,這三者的組合仍然會遇到一個性能瓶頸。硬盤的訪問速度要比內存慢很多,而每一次內存交換,都需要把一大段連續的內存數據寫到硬盤上。所以,如果內存交換的時候,交換的是一個很佔內存空間的程序,這樣整個機器都會顯得卡頓。

  既然問題出在內存碎片和內存交換的空間太大上,那麼解決問題的辦法就是,少出現一些內存碎片。另外,當需要進行內存交換的時候,讓需要交換寫入或者從磁盤裝載的數據更少一點,這樣就可以解決這個問題。這個辦法,在現在計算機的內存管理裏面,就叫作內存分頁(Paging)。

  和分段這樣分配一整段連續的空間給到程序相比,分頁是把整個物理內存空間切成一段段固定尺寸的大小。而對應的程序所需要佔用的虛擬內存空間,也會同樣切成一段段固定尺寸的大小。這樣一個連續並且尺寸固定的內存空間,我們叫頁(Page)。從虛擬內存到物理內存的映射,不再是拿整段連續的內存的物理地址,而是按照一個一個頁來的。頁的尺寸一般遠遠小於整個程序的大小。

  Linux 下內存頁大小的查看方式: getconf PAGE_SIZE

  分頁的方式在加載程序的時候,不再需要一次性都把程序加載到物理內存中。當要讀取特定的頁,卻發現數據並沒有加載到物理內存裏的時候,就會觸發一個來自於 CPU 的缺頁錯誤(Page Fault)。操作系統會捕捉到這個錯誤,然後將對應的頁,從存放在硬盤上的虛擬內存裏讀取出來,加載到物理內存裏。

  這種方式,可以運行那些遠大於我們實際物理內存的程序。同時,這樣一來,任何程序都不需要一次性加載完所有指令和數據,只需要加載當前需要用到就行了。

5 動態鏈接庫

![內存佔用的問題][內存佔用的問題]

  在 Windows 下,共享庫文件就是.dll 文件,也就是 Dynamic-Link Libary(DLL,動態鏈接庫)。在 Linux 下,共享庫文件就是.so 文件,也就是 Shared Object(一般也稱之爲動態鏈接庫)。

![動態鏈接庫][動態鏈接庫]

  對於所有動態鏈接共享庫的程序來講,雖然共享庫用的都是同一段物理內存地址,但是在不同的應用程序裏,它所在的虛擬內存地址是不同的。

![共享同一段物理內存][共享同一段物理內存]

5.1 動態鏈接庫尋址

![show_me_poor][show_me_poor]

  在共享庫的 data section 裏面,保存了一張全局偏移表(GOT,Global Offset Table)。雖然共享庫的代碼部分的物理內存是共享的,但是數據部分是各個動態鏈接它的應用程序裏面各加載一份的。所有需要引用當前共享庫外部的地址的指令,都會查詢 GOT,來找到當前運行程序的虛擬內存裏的對應位置。而 GOT 表裏的數據,則是在加載一個個共享庫的時候寫進去的。

6 編碼與數字

  ASCII 碼

ASCII 碼

  ASCII 碼只表示了 128 個字符,一開始倒也堪用,畢竟計算機是在美國發明的。然而隨着越來越多的不同國家的人都用上了計算機,想要表示譬如中文這樣的文字,128 個字符顯然是不太夠用的。於是,計算機工程師們開始各顯神通,給自己國家的語言創建了對應的字符集(Charset)和字符編碼(Character Encoding)。

  而字符編碼則是對應字符集裏的這些字符,一一用二進制表示出來。Unicode 就可以用 UTF-8、UTF-16,乃至 UTF-32 來進行編碼,存儲成二進制。

7 門電路

8 浮點數和定點數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章