體系結構與操做系統拾遺

victor-aznabaev-pjTU9Edzc1g-unsplash

體系結構與操做系統拾遺

Part1. 體系結構基礎

1. 馮·諾依曼體系結構

  1. 計算機處理的數據和指令一概用二進制數表示
  2. 順序執行程序
    1. 計算機運行過程當中,把要執行的程序和處理的數據首先存入主存儲器(內存),計算機執行程序時,將自動地並按順序從主存儲器中取出指令一條一條地執行,這一律念稱做順序執行程序。
  3. 計算機硬件由運算器、控制器、存儲器、輸入設備和輸出設備五大部分組成。

2. 數據的機內表示

二進制表示

  1. 機器數
    1. 因爲計算機中符號和數字是同樣的,都必須用二進制數串來表示,所以,正負號也必須用 0、1 來表示。
    2. 用最高位 0 表示正、1 表示負,這種正負號數字化的機內表示形式就稱爲 「機器數」,而相應的機器外部用正負號表示的數稱爲「真值」,將一個真值表示成二進制字串的機器數的過程就稱爲編碼。
  2. 原碼
    原碼就是符號位加上真值的絕對值,即用第一位表示符號,其他位表示值,好比若是是 8 位二進制:
    [+1]原 = 0000 0001
    [-1]原 = 1000 0001
    第一位是符號位,由於第一位是符號位,因此 8 位二進制的取值範圍就是:
    [1111 1111, 0111, 1111] 即 [-127, +127]
    原碼是人腦最容易理解和計算表達方式。數組

  3. 反碼
    反碼的表示方法是:正數的反碼就是其自己,負數的反碼是在其原碼的基礎上,符號位不變,其他各個位取反。
    [+1] = 原碼:[0000 0001] = 反碼:[0000 0001]
    [-1] = 原碼:[1000 0001] = 反碼:[1111 1110]
    可見若是一個反碼錶示負數,人腦沒法直觀的看出它的數值,一般要將其轉換成原碼再計算。微信

  4. 補碼
    補碼的表示方法是:正數的補碼就是其自己,負數的補碼是在其原碼的基礎上,符號位不變,其他各位取反,最後 +1。(即在反碼的基礎上 +1)
    [+1] = 原碼:[0000 0001] = 補碼:[0000 0001]
    [-1] = 原碼:[1000 0001] = 補碼:[1111 1111]
    對於負數,補碼錶示方式也是人腦沒法直觀看出其數值的,一般也須要轉換成原碼再計算其數值。網絡

  5. 定點數與浮點數
    定點數是小數點固定的數。在計算機中沒有專門表示小數點的位,小數點的位置是約定默認的。通常固定在機器數的最低位以後,或是固定在符號位以後。前者稱爲定點純整數,後者稱爲定點純小數。
    定點數表示法簡單直觀,可是數值表示的範圍過小,運算時容易產生溢出。函數

    浮點數是小數點的位置能夠變更的數。爲增大數值表示範圍,防止溢出,採用浮點數表示法。浮點表示法相似於十進制中的科學計數法。編碼

    在計算機中,一般把浮點數分紅階碼和尾數兩部分來表示,其中階碼通常用補碼定點整數表示,尾數通常用補碼或原碼定點小數表示。爲保證不損失有效數字,對尾數進行格式化處理,也就是平時所說的科學計數法,即保證尾數的最高位爲 1,實際數值經過階碼進行調整。
    階符表示指數的符號位、階碼錶示冪次、數符表示尾數的符號位、尾數表示格式化後的小數值。
    N = 尾數 x 基數階碼(指數)操作系統

位(Bit)、字節(Byte)、字(Word)

位(Bit):是電子計算機中最小的數據單位,每一位的狀態只能是 0 或 1.code

字節(Byte):8 個二進制構成 1 個字節(Byte),它是存儲空間的基本計量單位。1 個字節(Byte)能夠存儲一個英文字母或半個漢字,換而言之:1 個漢字佔據 2 個字節(Byte)的存儲空間。blog

字(Word):由若干個字節構成,字的位數叫作字長,不一樣檔次的機器有不一樣的字長。例如:一臺 8 位機,它的 1 個字就等於 1 個字節。若是是一臺 16 位機,那麼它的 1 個字就由 2 個字節構成,字長爲 16 位。字是計算機進行數據處理和運算的單位。接口

字節序

字節序(字節順序)是指佔內存多於一個字節類型的數據在內存中的存放順序,一般有小端、大端兩種字節順序。進程

小端字節序(Little Endian):指低字節數據存放在內存低地址處,高字節數據存放在內存高地址處;
大端字節序(Big Endian):指高字節數據存放在低地址處,低字節數據存放在高地址處。

基於 X86 平臺的 PC 機是小端字節序的,而有的嵌入式平臺則是大端字節序的。全部網絡協議也都是採用大端字節序的方式來傳輸數據的,因此有時咱們也會把大端字節序稱之爲:網絡字節序。

好比數字 0x12345678 在兩種不一樣字節序 CPU 中的存儲順序以下所示:

大端字節序(Big Endian)
低地址                                            高地址
---------------------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     12     |      34    |     56      |     78    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

小端字節序(Little Endian)
低地址                                            高地址
---------------------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     78     |      56    |     34      |     12    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

聯合體 union 的存放順序是全部成員都從低地址開始存放,利用該特性,就能判斷 CPU 對內存採用 Little-Endian 仍是 Big-Endian 模式讀寫。
示例代碼:

union test {
    short value;
    char str[sizeof(short)];
}example

void main()
{
    example.value = 0x0102;
    if (sizeof(short) == 2) {
        if (example.str[0] == 1 && example.str[1] == 2) {
            printf("大端字節序");
        } else if (example.str[0] == 2 && example.str[1] == 1) {
            printf("小端字節序");        
        } else {
            printf("結果未知");
        }
    }
}

字節對齊

現代計算機中內存空間都是按照 byte 劃分的,從理論上講彷佛對任何類型的變量的訪問能夠從任何地址開始,但實際狀況是在訪問特定類型變量的時候常常在特定的內存地址訪問,這就須要各類類型數據按照必定的規則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。

爲何要進行字節對齊?
  • 最根本的緣由是效率問題,字節對齊能提升存取數據的速度。
  • 某些平臺只能在特定的地址處訪問特定類型的數據

好比有的平臺每次都是從偶地址處讀取數據,對於一個 int 型的變量,若從偶地址單元處存放,則只需一個讀取週期便可讀取該變量,可是若從奇地址單元處存放,則須要 2 個讀取週期讀取該變量。

字節對齊的原則
  • 數據成員對齊規則:結構(struct)或聯合(union)的數據成員,第一個數據成員放在 offset 爲 0 的地方,之後每一個數據成員存儲的起初位置要從該成員大小或者成員的子成員大小(只要該成員有子成員,好比說是數組、結構體等)的整數倍開始,好比 int 在 32 位機爲 4 字節,則要從 4 的整數倍地址開始存儲。
  • 結構體做爲成員:若是一個結構體裏有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍地址開始存儲。(struct a 裏存有 struct bb 裏有 charintdouble 等元素,那麼 b 應該從 8 的整數倍開始存儲。)
  • 結構體的總大小,也就是 sizeof 的結果,必須使其內部最大成員的整數倍,不足的要補齊。

Part2. 操做系統基礎

1. 操做系統提供的服務

操做系統五大功能:

  • 做業管理
  • 文件管理
  • 存儲管理
  • 輸入輸出設備管理
  • 進程及處理機管理

2. 中斷與系統調用

中斷

中斷:計算機執行程序的過程當中,因爲出現了某些特殊事情,使得 CPU 暫停對程序的執行,轉而去執行處理這一事件的程序,等這些特殊事情處理完以後再回去執行以前的程序。
中斷分三類:

  1. 由計算機硬件異常或故障引發的中斷,稱爲內部異常中斷;
  2. 由程序中執行了引發中斷的指令而形成的中斷,稱爲軟中斷(這也是和咱們將要說明的系統調用相關的中斷)
  3. 由外部設備請求引發的中斷,稱爲外部中斷。

簡單說,對中斷的理解就是對一些特殊事情的處理。

與中斷緊密相連的一個概念就是中斷處理程序,當中斷髮生的時候,系統須要去對中斷進行處理,對這些中斷的處理是由操做系統內核中的特定函數進行的,這些處理中斷的特定的函數就是咱們所說的中斷處理程序。

另外一個與中斷緊密相連的概念是中斷的優先級,中斷的優先級說明的是當一箇中斷正在被處理的時候,處理器能接收的中斷的級別。中斷的優先級代表了中斷須要被處理的緊急程度,每一箇中斷都有一個對應的優先級,當處理器在處理某一中斷的時候,只有比這個中斷優先級高的中斷能夠被處理器接受而且被處理。優先級比這個當前正在被處理的中斷優先級要低的中斷將會被忽略。
中斷優先級:

機器錯誤 > 時鐘 > 磁盤 > 網絡設備 > 終端 > 軟件中斷

當發現軟件中斷時,其餘全部的中斷均可能發生並被處理;但當發生磁盤中斷時,就只有時鐘中斷和機器錯誤中斷能被處理了。

系統調用

進程的執行在系統上的兩個級別:用戶級(用戶態)和核心級(系統態)。

程序的執行通常是在用戶態下執行的,但當程序須要使用操做系統提供的服務時,好比說打開某一設備、建立文件、讀寫文件等,就須要向操做系統發生調用服務的請求,這就是系統調用。

Linux 系統有專門的函數庫來提供這些請求操做系統服務的入口,這個函數庫中包含了操做系統所提供的對外服務的接口,當進程發出系統調用以後,它所處的運行狀態就會由用戶態變成核心態。但這個時候,進程自己其實並無作什麼事情,這個時候是由內核在作相應的操做,去完成進程所提出的這些請求。

系統調用和中斷的關係在於:當進程發出系統調用申請的時候,會產生一個軟件中斷。產生這個軟件中斷之後,系統會去對這個軟中斷進行處理,這個時候進程就處於核心態了。

用戶態和核心態區別:

  1. 用戶態的進程能存取他們本身的指令和數據,但不能存取內核指令和數據(或其餘進程的指令和數據),然而,核心態下的進程可以存取內核和用戶地址。
  2. 某些機器指令是特權指令,在用戶態下執行特權指令會引發錯誤。

在系統中內核並非做爲一個與用戶進程平行的進程的集合,內核是爲用戶進程運行的。


更多幹貨文章

博客:www.qiuxuewei.com
微信公衆號:@開發者成長之路
公衆號二維碼

一個沒有雞湯只有乾貨的公衆號 ****************************************************

相關文章
相關標籤/搜索