程序員須要瞭解的硬核知識之控制硬件

應用和硬件的關係

咱們做爲程序員通常不多直接操控硬件,咱們通常經過 C、Java 等高級語言編寫的程序起到間接控制硬件的做用。因此你們不多直接接觸到硬件的指令,硬件的控制是由 Windows 操做系統 全權負責的。程序員

你必定猜到我要說什麼了,沒錯,我會說可是,任何事情沒有絕對性,環境的不一樣會形成結果的誤差。雖然程序員無法直接控制硬件,而且 Windows 屏蔽了控制硬件的細節,可是 Windows 卻爲你開放了 系統調用功能來實現對硬件的控制。在 Windows 中,系統調用稱爲 API,API 就是應用調用的函數,這些函數的實體被存放在 DLL 文件中。windows

image.png

下面咱們來看一個經過系統調用來間接控制硬件的實例ide

假如要在窗口中顯示字符串,就可使用 Windows API 中的 TextOut 函數。TextOut 函數的語法(C 語言)以下函數

BOOL TextOut{
  HDC hdc,                                         // 設備描述表的句柄
  int nXStart,                                    // 顯示字符串的 x 座標
  int nYStart,                                    // 顯示字符串的 y 座標
  LPCTSTR lpString,                                // 指向字符串的指針
  int cbString                                    // 字符串的文字數
}

那麼,在處理 TextOut 函數的內容時,Windows 作了些什麼呢?從結果來看,Windows 直接控制了做爲硬件的顯示器。但 Windows 自己也是軟件,因而可知,Windows 應該向 CPU 傳遞了某種指令,從而經過軟件控制了硬件。測試

Windows 提供的 TextOut 函數 API 能夠向窗口和打印機輸出字符。C 語言提供的 printf 函數,是用來在命令提示符中顯示字符串的函數。使用 printf 函數是沒法向打印機輸出字符的。

支持硬件輸入輸出的 IN 指令和 OUT 指令

Windows 控制硬件藉助的是輸入和輸出指令。其中具備表明性的兩個輸入輸出指令就是 INOUT 指令。這些指令也是彙編語言的助記符。spa

能夠經過 IN 和 OUT 指令來實現對數據的讀入和輸出,以下圖所示操作系統

image.png

也就是說,IN 指令經過指定的端口號輸入數據,OUT 指令則是把 CPU 寄存器中存儲的數據輸出到指定端口號的端口。3d

那麼這個端口號端口是什麼呢?你感受它像不像港口同樣?經過標註哪一個港口而後進行貨物的運送和運出?指針

下面咱們來看一下官方是如何定義端口號和端口的code

還記得計算機組成原理中計算機的五大組成部分嗎,再來回顧一下:運算器、控制器、存儲器、輸入設備和輸出設備。咱們今天不談前三個,就說說後面兩個輸入設備和輸出設備,這兩個與咱們本節主題息息相關。

那麼問題來了,IO設備如何實現輸入和輸出的呢?計算機主機中,附帶了用來鏈接顯示器以及鍵盤等外圍設備的鏈接器。 而鏈接器的內部,都鏈接有用來交換計算機主機同外圍設備之間電流特性的 IC。若是 IC 你不明白是什麼的話,能夠參考做者的文章 程序員須要瞭解的硬核知識以內存 進行了解。這些 IC 統稱爲 IO 控制器

IO 是 Input/Output 的縮寫。顯示器、鍵盤等外圍設備都有各自專用的 I/O 控制器。I/O 控制器中有用於臨時保存輸入輸出數據的內存。這個內存就是 端口(port)。端口你就能夠把它理解爲咱們上述說的 港口。IO 控制器內部的內存,也被稱爲寄存器,不要慌,這個寄存器和內存中的寄存器不同。CPU 內存的寄存器是用於進行數據運算處理的,而IO中的寄存器是用於臨時存儲數據的。

在 I/O 設備內部的 IC 中,有多個端口。因爲計算機中鏈接着不少外圍設備,所以也就有不少 I/O 控制器。固然也會有多個端口,一個 I/O 控制器能夠控制多個設備,不只僅只能控制一個。各端口之間經過 端口號 進行區分。

端口號也被稱爲 I/O地址 。IN 指令和 OUT 指令在端口號指定的端口和 CPU 之間進行數據的輸入和輸出。這跟經過內存的地址來對內存進行讀寫是同樣的道理。

image.png

測試輸入和輸出程序

首先讓咱們利用 IN 指令和 OUT 指令,來進行一個直接控制硬件的實驗。假如試驗的目的是讓一個計算機內置的喇叭(蜂鳴器)發出聲音。蜂鳴器封裝在計算機內部,但它也是外圍設備的一種。

用匯編語言比較繁瑣,此次咱們用 C 語言來實現。在大部分 C 語言的處理(編譯器的種類)中,只要使用 _asm{ 和 }括起來,就能夠在其中記述助記符。也就是說,採用這種方式就可以使用 C 語言和彙編語言混合的源代碼。

在 AT 兼容機中,蜂鳴器的默認端口號是 61H ,末尾的 H 表示的是十六進制數的意思。用 IN 指令經過該端口號輸入數據,並將數據的低2位設定爲 ON,而後再經過該端口號用 OUT 指令輸出數據,這時蜂鳴器就會發出聲音。一樣的方法,將數據的低2位設定爲 OFF 並輸出後,蜂鳴器就中止工做。

位設定爲 ON 指的是將該位設定爲1,位設定爲 OFF 指的是將該位設定爲0 。把位設定爲 ON,只須要把想要設定爲 ON 的位設定爲1,其餘位設定爲0後進行 OR 運算便可。因爲這裏須要把低2位置爲1,所以就是和 03H 進行 OR 運算。03H 用8爲二進制來表示的話是 00000011。因爲即使高6位存在着具體意義。和0進行OR運算後也不會發生變化,於是就和 03H 進行 OR 運算。把位設定爲 OFF,只須要把想要置 OFF 的位設定爲0,其餘位設定爲1後進行 AND 運算便可。因爲這裏須要把低2位設定爲0,所以就要和 FCH 進行 AND 運算。在源代碼中,FCH 是用 0FCH 來記述的。在前面加 0 是彙編語言的規定,表示的是以 A - F 這些字符開頭的十六進制數是數值的意思。0FCH 用8位二進制數來表示的話是 11111100。因爲即使高6位存在着具體意義,和1進行 AND 運算後也不會產生變化,於是就是同 0FCH 進行 OR 運算。

void main(){
  
  // 計數器
  int i;
  
  // 蜂鳴器發聲
  _asm{
    IN  EAX, 61H
    OR    EAX, 03H
    OUT    61H, EAX
  }
  
  // 等待一段時間
  for(i = 0;i < 1000000;i++);
  
  // 蜂鳴器中止發生
  _asm{
    IN  EAX, 61H
    AND EAX, 0FCH
    OUT 61H, EAX
  }
}

咱們對上面的代碼進行說明,main 是 C 語言程序起始位置的函數。在該函數中,有兩個用 _asm{} 圍起來的部分,它們中間有一個使用 for 循環的空循環

首先是蜂鳴器發聲的部分,經過 IN EAX,61H(助記符不區分大小寫)指令,把端口 61H 的數據存儲到 CPU 的 EAX 寄存器中。接下來,經過 OR EAX,03H 指令,把 EAX 寄存器的低2位設定成 ON。最後,經過 OUT 61H,EAX 指令,把 EAX 寄存器的內容輸出到61端口。使蜂鳴器開始發音。雖然 EAX 寄存器的長度是 32 位,不過因爲蜂鳴器端口是8位,因此只需對下8位進行OR運算和AND運算就能夠正常工做了。

其次是一個重複100次的空循環,主要是爲了在蜂鳴器開始發音和中止發音之間稍微加上一些時間間隔。由於如今計算機器的運行速度很是快,哪怕是 100 萬次循環,也幾乎是瞬時間完成的。

而後是用來控制器蜂鳴器中止發聲的部分。首先,經過 IN EAX,61H 指令,把端口 61H 的數據存儲到 CPU 的 EAX 寄存器中。接下來,經過 AND EAX,0FCH 指令,把 EAX 寄存器的低2位設定爲 OFF。最後,經過 OUT 61H,EAX 指令,把寄存器的 EAX 內容輸出到61號端口,使蜂鳴器中止發音。

外圍設備的中斷請求

IRQ(Interrupt Request) 表明的就是中斷請求。IRQ 用來暫停當前正在運行的程序,並跳轉到其餘程序運行的必要機制。該機制被稱爲 處理中斷。中斷處理在硬件控制中擔當着重要的角色。由於若是沒有中斷處理,就有可能沒法順暢進行處理的狀況。

從中斷處理開始到請求中斷的程序(中斷處理程序)運行結束以前,被中斷的程序(主程序)的處理是中止的。這種狀況就相似於在處理文檔的過程當中有電話打進來,電話就至關因而中斷處理。假如沒有中斷處理的發生,就必須等到文檔處理完成後纔可以接聽電話。因而可知,中斷處理有着巨大的價值,就像是接聽完電話後會返回原來的文檔做業同樣,中斷程序處理完成後,也會返回到主程序中繼續。

image.png

實施中斷請求的是鏈接外圍設備的 I/O 控制器,負責實施中斷處理的是 CPU,外圍設備的中斷請求會使用不一樣於 I/O 端口的其餘編號,該編號稱爲中斷編號。在控制面板中查看軟盤驅動器的屬性時,IRQ處現實的數值是 06,表示的就是用06號來識別軟盤驅動器發出的請求。還有就是操做系統以及 BIOS 則會提供響應中斷編號的中斷處理程序。

BIOS(Basic Input Output System): 位於計算機主板或者擴張卡上內置的 ROM 中,裏面記錄了用來控制外圍設備的程序和數據。

假若有多個外圍設備進行中斷請求的話, CPU 須要作出選擇進行處理,爲此,咱們能夠在 I/O 控制器和 CPU 中間加入名爲中斷控制器的 IC 來進行緩衝。中斷控制器會把從多個外圍設備發出的中斷請求有序的傳遞給 CPU。中斷控制器的功能至關於就是緩衝。下面是中斷控制器功能的示意圖

image.png

CPU 在接受到中斷請求後,會把當前正在運行的任務中斷,並切換到中斷處理程序。中斷處理程序的第一步處理,就是把 CPU 全部寄存器的數值保存到內存的棧中。在中斷處理程序中完成外圍設備的輸入和輸出後,把棧中保存的數值還原到 CPU 寄存器中,而後再繼續進行對主程序的處理。

假如 CPU 寄存器數值尚未還原的話,就會影響到主程序的運行,甚至還有可能會使程序意外中止或發生運行時異常。這是由於主程序在運行過程當中,會用到 CPU 寄存器進行處理,這時候若是忽然插入其餘程序的運行結果,此時 CPU 必然會受到影響。因此,在處理完中斷請求後,各個寄存器的值必需要還原。只要寄存器的值保持不變,主程序就能夠像沒有發生過任何事情同樣繼續處理。

image.png

用中斷來實現實時處理

中斷是指計算機運行過程當中,出現某些意外狀況需主機干預時,機器能自動中止正在運行的程序並轉入處理新狀況的程序,處理完畢後又返回原被暫停的程序繼續運行。

在程序的運行過程當中,幾乎無時無刻都會發生中斷,其緣由就是爲了實時處理外部輸入的數據,雖然程序也能夠在不會中斷的基礎上處理外部數據,可是那種狀況下,主程序就會頻繁的檢查外圍設備是否會有數據輸入。因爲外圍設備會有不少個,所以有必要按照順序來調查。按照順序檢查多個外圍設備的狀態稱爲 輪詢。對於計算機來講,這種採用輪詢的方式不是很合理,若是你正在檢查是否有鼠標輸入,這時候發生了鍵盤輸入該如何處理呢?結果一定會致使文字的實時處理效率。因此即時的中斷可以提升程序的運行效率。

上面只是中斷的一種好處,下面彙總一下利用中斷可以帶來的正面影響

  • 提升計算機系統效率。計算機系統中處理機的工做速度遠高於外圍設備的工做速度。經過中斷能夠協調它們之間的工做。當外圍設備須要與處理機交換信息時,由外圍設備向處理機發出中斷請求,處理機及時響應並做相應處理。不交換信息時,處理機和外圍設備處於各自獨立的並行工做狀態。
  • 維持系統可靠正常工做。現代計算機中,程序員不能直接干預和操縱機器,必須經過中斷系統向操做系統發出請求,由操做系統來實現人爲干預。主存儲器中每每有多道程序和各自的存儲空間。在程序運行過程當中,如出現越界訪問,有可能引發程序混亂或相互破壞信息。爲避免這類事件的發生,由存儲管理部件進行監測,一旦發生越界訪問,向處理機發出中斷請求,處理機當即採起保護措施。
  • 知足實時處理要求。在實時系統中,各類監測和控制裝置隨機地向處理機發出中斷請求,處理機隨時響應並進行處理。
  • 提供故障現場處理手段。處理機中設有各類故障檢測和錯誤診斷的部件,一旦發現故障或錯誤,當即發出中斷請求,進行故障現場記錄和隔離,爲進一步處理提供必要的依據。

利用 DMA 實現短期內大量數據傳輸

上面咱們介紹了 I/O 處理和中斷的關係,下面咱們來介紹一下另一個機制,這個機制就是 DMA(Direct Memory Access)。DMA 是指在不經過 CPU 的狀況下,外圍設備直接和主存進行數據傳輸。磁盤等硬件設備都用到了 DMA 機制,經過 DMA,大量數據能夠在短期內實現傳輸,之因此這麼快,是由於 CPU 做爲中介的時間被節省了,下面是 DMA 的傳輸過程

image.png

I/O 端口號、IRQ、DMA 通道能夠說是識別外圍設備的3點組合。不過,IRQ、DMA 通道並非全部外圍設備都具有的。計算機主機經過軟件控制硬件時所須要的信息的最低限,是外圍設備的 I/O 端口號。IRQ 只對須要中斷處理的外圍設備來講是必須的,DMA 通道則只對須要 DMA 機制的外圍設備來講是必須的。假如多個外圍設備都設定成相同的端口號、IRQ 和 DMA 通道的話,計算機就沒法正常工做,會提示 設備衝突

文字和圖片的顯示機制

你知道文字和圖片是如何顯示出來的嗎?事實上,若是用一句話來簡單的歸納一下該機制,那就是顯示器中顯示的信息一直存儲在某內存中。該內存稱爲VRAM(Video RAM)。在程序中,只要往 VRAM 中寫入數據,該數據就會在顯示器中顯示出來。實現該功能的程序,是由操做系統或者 BIOS 提供,並藉助中斷來進行處理。

MS-DOS 時代,對於大部分計算機來講,VRAM 都是主內存的一部分。在現代計算機中,顯卡等專用硬件中通常都配置有與主內存相獨立的 VRAM 和 GPU(Graphics Processing Unit),也叫作圖形處理器或者圖形芯片。這是由於,對常常描繪圖形的 windows 來講,數百兆的 VRAM 都是必需的。

image.png

用軟件來控制硬件聽起來好像很難,但實際上只是利用輸入輸出指令同外圍設備進行輸入輸出而已。中斷處理是根據須要來使用的功能選項。DMA 則直接交給對應的外圍設備便可。

雖然計算機領域新技術在不斷涌現,可是計算機所能處理的事情,始終只是對輸入的數據進行運算,並把結果輸出,這一點是永遠不會發生變化的。

文章參考:

《程序是怎樣跑起來的》

中斷控制器

中斷

相關文章
相關標籤/搜索