電腦系統:硬件與軟件

歡迎來到電腦科學中最基礎的章節之一!本節「硬件與軟件」旨在為大家打好基礎,理解電腦究竟是如何運作的。如果這些術語聽起來很抽象,請不用擔心;我們將會使用簡單的例子,拆解電腦的物理部件如何與指令互動,從而發揮它們的功用。

掌握這一課題至關重要,因為它為你所有的編程知識提供了背景。你需要了解當你運行程式時,電腦底層究竟發生了什麼!


3.6.1 基礎知識:硬件與軟件

定義核心概念

每個電腦系統都是建立在兩個基本要素的互動之上:硬件 (Hardware)軟件 (Software)

1. 硬件 (Hardware)

硬件是指電腦系統的電子組件。它是你可以觸摸(或者感受到它散發出的熱量!)的物理實體。

  • 例子: 處理器 (CPU)、主記憶體 (RAM)、顯示器、鍵盤以及連接它們的電纜。

重點總結: 硬件是執行指令的機器。


2. 軟件 (Software)

軟件是指使用硬件來執行的指令序列(程式)。

  • 它是無形的——你無法觸摸軟件本身,只能觸摸儲存它的儲存裝置。
  • 軟件是指揮中心;它精確地告訴硬件執行什麼任務以及何時執行。

關係: 沒有軟件驅動,硬件將毫無用處;而沒有底層的硬件基礎設施,軟件也無法運行。


3.6.2 軟件深度剖析:系統軟件與應用軟件

根據用途,軟件通常被分為兩大類。

1. 系統軟件 (System Software)

系統軟件旨在管理和控制電腦硬件,並為應用軟件提供運行平台。

  • 它確保電腦運作順暢。
  • 類比: 如果你的電腦是一輛汽車,系統軟件就是引擎和轉向系統。

2. 應用軟件 (Application Software)

應用軟件旨在為用戶執行特定任務。

  • 這是讓用戶能進行生產力工作或娛樂的軟件。
  • 例子: 文書處理器、網頁瀏覽器、電子遊戲、照片編輯工具。

核心系統軟件組件的功能

a. 作業系統 (Operating Systems, OS)

作業系統 (OS)(如 Windows、macOS 或 Linux)是系統軟件中最關鍵的部分。

作業系統的主要作用是向用戶和其他軟件隱藏硬件的複雜性。當程式需要儲存檔案時,它是要求作業系統去處理,而不是直接與硬碟溝通。

作業系統通過幾個關鍵功能來管理系統資源:

  • 排程 (Scheduling): 決定處理器接下來應運行哪些任務或進程,以及運行多久,確保所有運行的程式都能公平地獲取 CPU 資源。
  • 記憶體分配 (Memory Allocation): 管理主記憶體 (RAM)。當程式和數據載入時,作業系統會分配空間,並確保不同程式不會干擾彼此的記憶體空間。
    (注意:你只需要了解主記憶體是如何分配的,無需涵蓋虛擬記憶體。)
  • 輸入/輸出裝置管理 (I/O Device Management): 處理來自周邊裝置(打印機、滑鼠、螢幕等)的輸入和輸出 (I/O)。它管理這些裝置與系統其餘部分之間的通訊。
  • 中斷處理 (Interrupt Handling): 處理來自硬件或軟件的突發優先信號(中斷),例如按下按鍵、打印機缺紙或計時器歸零。

中斷處理概念步驟:

  1. 發生事件(例如點擊滑鼠)。
  2. 硬件向 CPU 發送中斷 (Interrupt) 信號。
  3. CPU 暫停當前的工作(取指令-執行週期)。
  4. CPU 儲存當前狀態(易失性環境),以便稍後能返回該處。
  5. CPU 識別中斷類型,並執行相應的中斷服務常式 (ISR)
  6. ISR 處理請求(例如處理滑鼠點擊)。
  7. 一旦 ISR 完成,CPU 恢復已儲存的環境,並繼續執行原來的任務。
b. 公用程式 (Utility Programs)

這些程式增加了額外功能,以協助管理電腦系統

  • 例子: 病毒檢測程式(保護檔案)或壓縮程式(減少檔案大小)。
c. 函式庫 (Libraries)

函式庫是預先編寫好的、可重用的常式(子常式/代碼)集合,供程式設計師使用。它們能節省時間,因為程式設計師無需從零開始編寫常見功能(如計算平方根或繪製圖形)。

d. 翻譯程式 (Translators)

這是將人類編寫的代碼轉換為 CPU 可執行的機器碼的程式(將在下一節詳細介紹)。

快速複習:系統軟件功能

作業系統角色: 隱藏硬件複雜性,管理資源。
四大關鍵任務: 排程、記憶體、I/O、中斷。
公用程式: 用於系統管理的工具(如防毒)。
函式庫: 供程式設計師使用的可重用代碼塊。


3.6.3 編程語言與翻譯軟件

電腦只懂二進制(0 和 1),但人類編寫代碼使用的語言則易讀得多。翻譯程式就是填補這一鴻溝的橋樑。

3.6.3.1 編程語言的分類

編程語言大致上根據其與硬件的接近程度進行分類。

1. 低階語言 (Low-Level Languages)(接近硬件)

這些語言需要對處理器架構有深厚的了解。

  • 機器碼 (Machine Code): 這是最極致的低階語言。
    • 完全以二進制(0 和 1 的序列)表達。
    • 可由 CPU 直接執行。
    • 用機器碼編寫程式極其困難且容易出錯。
  • 組合語言 (Assembly Language): 使用助憶碼 (mnemonics)(短縮寫)來代表機器碼指令。
    • 例子: 與其寫二進制序列,你可能會寫 ADDJUMP
    • 組合語言指令與機器指令之間通常存在 1:1 的對應關係。

低階語言的優點:

  • 以低階語言編寫的程式速度極快
  • 它們記憶體效率極高(使用最少的資源)。
  • 它們允許對硬件進行直接控制,這對於作業系統或嵌入式系統至關重要。

低階語言的缺點:

  • 它們難以編寫、除錯和維護
  • 它們不具備可攜性 (portability);為某種 CPU 編寫的代碼無法在另一種 CPU 上運行。
2. 高階語言 (High-Level Languages)(接近用戶)

這些語言類似於人類語言(英文、數學),並抽象化了硬件的複雜性。

  • 命令式高階語言: 一種語言(如 Python、Java、C#),程式設計師在其中提供一系列指令,描述執行任務所需的流程(即「如何」做)。
  • 它們更容易學習、除錯,且通常在不同硬件之間具有可攜性。
你知道嗎?

儘管常會提到「世代」(例如第二代、第三代語言),但你只需要將它們分類為低階(機器碼、組合語言)和高階(命令式語言)即可。

3.6.3.2 程式翻譯器的類型

由於 CPU 只懂機器碼,高階原始碼必須經過翻譯。這通常由三種主要類型的軟件完成:

1. 組譯器 (Assembler)

組譯器組合語言翻譯成機器碼(目標代碼)。由於指令之間存在 1:1 的對應關係,這一過程非常直接。

2. 編譯器 (Compiler)

編譯器在程式執行之前,將整個程式(原始碼)翻譯成可執行檔案(目標代碼)。

  • 流程: 原始碼 -> 編譯器 -> 目標代碼(可執行檔)-> 運行。
  • 速度: 一旦編譯完成,程式運行速度非常快,因為所有的翻譯工作都在執行前完成。
  • 除錯: 錯誤在編譯後一次性報告,這使得初步除錯稍顯困難。
  • 原始碼 vs. 目標代碼: 原始碼 (Source code) 是人類可讀的原始代碼。目標代碼 (Object code) 是由翻譯器產生的機器可讀二進制輸出。
3. 解釋器 (Interpreter)

解釋器在程式運行時,逐行翻譯並執行程式。

  • 流程: 原始碼 -> (解釋器翻譯並執行第 1 行)-> (翻譯並執行第 2 行)-> ...
  • 速度: 整體執行速度通常比編譯後的代碼慢,因為翻譯工作在每次程式運行時都會重複發生。
  • 除錯: 除錯較容易,因為當某一行失敗時,錯誤會立即被報告。
何時使用哪種方式?(編譯 vs. 解釋)
  • 編譯適用於: 發佈給公眾使用的商業軟件,其中速度和保護原始碼是優先考量。
  • 解釋適用於: 開發和測試過程中,或者對於可攜性至關重要的語言(如網頁腳本)。

中間語言 (Bytecode)

一些現代高階語言(如 Java)使用兩步翻譯過程,產生一種中間語言(通常稱為字節碼 Bytecode)。

  • 為什麼使用中間語言?
    1. 可攜性: 中間代碼不綁定於特定處理器;它是與機器無關的。
    2. 安全性: 可以在執行前對中間代碼執行安全性檢查。
    3. 記憶體: 中間語言代碼通常比完整的機器碼使用更少的記憶體。
  • 使用方式:
    1. 虛擬機 (Virtual Machine, VM) 解釋中間代碼以執行它。
    2. 或者,即時編譯器 (Just-In-Time compiler, JIT) 會在執行前,將中間代碼轉換為適合當前運行電腦的機器碼。

重點總結:翻譯週期

高階代碼需要翻譯(編譯器或解釋器)才能運行。
低階組合代碼需要組譯器
中間代碼能提供可攜性