You are on page 1of 38

系統程式 – 理論與實務

第 12 章、系統軟體

作者:陳鍾誠

旗標出版社
1.1 簡介:何謂系統程式?
 System Software v.s System Programming

 System Software ( 系統軟體 )

 凡是專門設計給程式設計師使用的軟體,就被稱為系統軟體,而設計給一般大

眾使用的軟體,則稱為應用軟體。

 System Programming ( 系統程式 )

 與『作業系統』或『電腦系統』相關的程式。

 通常與電腦硬體有密切的關係。
System Software
 程式設計師專用的軟體 一般使用者所用的軟體
 組譯器 試算表
排版軟體
 載入器
瀏覽器
 連結器
…
 巨集處理器

 編譯器

 直譯器

 虛擬機 應用軟體

 模擬器
系統軟體
 作業系統
System Programming
電腦硬體相關的程式
 作業系統相關的程式
組合語言
行程管理 C 語言
執行緒 嵌入式系統

行程通訊
系統程式
並行控制

記憶體管理
些不是系統程式?
檔案輸出入
遊戲程式
驅動程式 資料庫程式
應用程式
多媒體程式
本書所採用的角度
 廣義的系統軟體 (System Software)

程式設計師專用的軟體

 廣義的系統程式 (System Programming)

與電腦硬體相關的程式

與作業系統相關的程式
本書的架構
 第 1 章、系統軟體 第 7 章、巨集處理器
 第 2 章、電腦的硬體結構 第 8 章、高階語言
 第 3 章、組合語言 第 9 章、編譯器
 第 4 章、組譯器 第 10 章、虛擬機與模擬器
 第 5 章、連結與載入 第 11 章、作業系統
 第 6 章、嵌入式系統 第 12 章、系統軟體實作
圖 1.1 本書的章節導引圖
組合語言 高階 語言 (C)
(第 3 章) (第 8 章)

系統軟體 ( 第 1 章 ) 巨集處理器 ( 第 7 章 )
嵌入式系統 ( 第 6 章 )
系統軟體實作 ( 第 12 章 )
組譯器 ( 第 4
編譯器 ( 第 9 章 ) 直譯器 ( 第 8 章 )
章)

其他目的檔
目的檔 ( 第 5 章 )
(第 5 章)

連結器 ( 第 5 章 )

執行檔 ( 第 5 章 )
函式庫
(第 5 章)
載入器 ( 第 5 章 )

執行

虛擬機與模擬器 ( 第 10
作業系統 ( 第 11 章 )
章)

電腦的硬體結構 ( 第 2 章 )
1.2 電腦硬體的基本概念
 馮紐曼電腦
處理器 (CPU)

記憶體 (Memory)

匯流排 (Bus)

輸出裝置 (Output device)

輸入 裝置 (Input device)

 公式
Computer = CPU+BUS+Memory+Input+Output
馮紐曼電腦架構
ALU 暫存器
R0
算術邏輯單元

RK
記憶體

Control Unit IR
SW
控製單元
PC

內部匯流排 Bus 輸出入單元

控制匯流排
資料匯流排
位址匯流排

輸出入
輸出裝置 輸入裝置
控制器
圖 1.2 現代電腦的抽像架構 – 馮紐曼結構
馮紐曼電腦的運作方式
 CPU 、記憶體、與輸出入裝置之間,是透過匯流排進行溝通

 CPU 可以將資料透過匯流排傳給記憶體,也可以接收從記憶體傳來的資

 當 CPU 想要進行輸出,例如將資料傳送給螢幕或寫到硬碟時,也是透
過匯流排將資料傳到該輸出裝置。

 當資料進入到輸入裝置後,也是透過匯流排將資料傳送給 CPU 。
CPU 的內部結構
 CPU = ALU+ 控制單元 + 內部匯流排 + 暫存器 + 輸出入單元

ALU 暫存器
R0
算術邏輯單元

RK

Control Unit IR
SW
控製單元
PC

內部匯流排 Bus 輸出入單元

 CPU 可以說是電腦當中的小型電腦,只是其記憶單元很少,只有幾個暫

存器而已
指令的執行過程
 階段 1 :提取階段
 步驟 1 、提取指令 : IR = [PC]
 步驟 2 、更新計數器 : PC = PC + 4

 階段 2 :解碼階段
 步驟 3 、解碼 :控制單元對 IR 進行解碼

   階段 3 :執行階段
 步驟 4 、設定 :設定資料流向開關與 ALU 的運算模式
 步驟 5 、執行 :資料流入 ALU 後流回指定的暫存器
指令 ADD R1, R2, R3 的執行過

 步驟 1 、提取指令 : IR = [PC]

 步驟 2 、更新計數器 : PC = PC + 4

 步驟 3 、解碼

 控制單元解碼 IR ,取得運算元 ADD 、目標暫存器 R1 與來源暫存器 R2, R3 。

 步驟 4 、設定:

 設定 R2 , R3 流向 ALU 的開關,設定 ALU 運算為加法,設定 ALU 輸出流向 R1 。

 步驟 5 、執行:

 執行並等待一小段週期,讓資料正確流出與流入。

 結果: R1 = R2 + R3 。
程式的載入過程
當程式被編譯成機器碼後,通常以二進位形式儲存

在目的檔或執行檔中。

在執行時,載入器會將執行檔會放入記憶體內。

最後,載入器會將 CPU 的控制權交給該程式,於

是程式開始執行。
程式的執行過程
從起始指令開始,處理器會一次提取一個指令

循序的執行每個指令,一個接著一個執行,直到出

現分支跳躍指令為止。

當分支跳躍指令被執行時,程式的流程會改變,這

使得程式可以具備迴圈,邏輯判斷等能力。
1.3 組合語言的角色
 學習組合語言是理解電腦軟硬體架構的捷徑

 組合語言扮演了軟體與硬體的中介橋樑

 整個 CPU 的設計精神可以從組合語言中觀察得到

 程式設計師可透過組合語言理解處理器的功能
組合語言優勢與缺點
 優點

 執行快速、可控制電腦硬體。

 程式設計師可以透過學習組合語言,理解電腦的硬體結構

 缺點

 多樣性:有多少種 CPU ,通常就有多少種組合語言,有時因組譯器的設計不同

,同一種 CPU 有很多種組合語言語法。


 組合語言很難學,商業用處理器的組合語言都有很多怪僻。

 組合語言難以跨越平台,換到另一台電腦上程式需重寫。
本書所採用的組合語言
一顆刻意簡化過的處理器 - CPU0 。

指令集與指令格式都很簡單。

容易學習,有助於理解『組合語言與目的檔之間的

對照關係』。
機器語言
 範例一: 00010011000100100011000000000000

 範例二: 0001 0011 0001 0010 0011 0000 0000 0000

 範例三: 13 12 30 00

 範例四: ADD R1, R2, R3


組合語言的常見指令
 指令 1 : ADD R1, R2, R3

 指令 2 : SUB R1, R2, R3

 指令 3 : ADD R2, R3, R1

 指令 4 : LD R1, [300]

 指令 5 : ADD R1, R2, [300]

 指令 6 : ADD R1, R2, COUNT

 指令 7 : ADD R1, COUNT

 指令 8 : ADD COUNT
1.4 高階語言的用途
 語言: C/C++/C#, VB, Java, Ruby, Perl, Python, PHP …

 執行:編譯、解譯、虛擬機器、…

 編譯:執行快速

 解譯:執行很慢、約較編譯式慢上數十倍

 虛擬機器:速度中等

 採用立即編譯 (JIT) 技術時,速度可達編譯式的一半


C 語言
 大部分的資訊工程系學生所學習的第一個語言

 C 語言是 K&R 兩人於發明 UNIX 時設計的

 設計上特別考慮了許多系統程式的因素
 組合語言的銜接

 硬體的控制

 執行速度的考量

 UNIX 的成功也帶動了 C 語言的進一步發展

 C 語言是系統程式、嵌入式系統與作業系統等領域的首選語言
C 語言的特點
 快速

 可用指標進行記憶體映射輸出入,以便控制硬體

 與組合語言連結容易

 許多作業系統都是用 C 語言撰寫的
UNIX, Linux, Windows, FreeBSD, ….
1.5 實務案例
1.5.1 GNU 開發工具

1.5.2 Visual Studio


1.5.1 GNU 開發工具
GNU 工具

開放原始碼 , 由 Richard Stallman 發起的

Linux 也是用 GNU 工具撰寫的

支援處理器非常眾多
 x86, IA32,ARM,MIPS,PowerPC, …
GNU 工具的開發環境
 在 Linux 中預設就有 GNU 工具。

 在 MS. Windows 中可用 Cygwin 環境,其中包含了大部


分 Linux 中常用的指令,當然也包含 GNU 工具。

 安裝時記得勾選 All/Devel/{gcc, binutils, make} 等選項

 安裝完後選『開始 / 所有程式 /Cygwin/Cygwin Bash Shell 』進

入 Cygwin 的 bash 命令列環境。


Cygwin 的命令列環境
GNU 的常用工具列表
工具 工具類型 說明
gcc C 語言編譯器 範例: gcc hello.c -o hello.o
GNU C Compiler
as 組譯器 範例: as hello.s -o hello.o
Assembler 說明:將 hello.s 組譯為 hello.o
ld 連結器 範例: ld -o abc.o a.o b.o c.o
Linker 說明:將 a.o, b.o, c.o 連結成執行檔 abc.o
Ar 函式庫製作 範例: ar -r libabc.a a.o b.o c.o
Archive 說明:將 a.o, b.o, c.o 包裝成函數庫 libabc.a
Nm name mangling 範例: nm hello.o
目標檔中的符號 說明:看 hello.o 目標檔的符號表。
objdump Object File Dump 範例: objdump -x hello.o
目標檔傾印 說明:查看目標檔資訊
objcopy Object File Copy 範例: objcopy -O binary hello.elf hello.bin
複製 / 轉換目標檔 說明:將 elf 檔轉換為 binary 檔
strip strip 範例: strip a.o
去除除錯資訊 說明:把 a.o 當中的符號表與除錯資訊去除。
Strings 觀看字串表 範例: strings a.o
說明:觀看 a.o 檔中的字串表,會顯示符號名稱與分
段名稱。
Ltrace 追蹤函數呼叫路徑 範例: ltrace a.o
說明:追蹤函數呼叫路徑 ( 在 Cygwin 中沒有 ) 。
GNU 工具使用的基本流程
main.c main.o

sum.c gcc sum.o ld executable

libm.a

printf.c printf.o

putc.c gcc putc.o ar libc.a

kprintf.c kprintf.o
編譯器 gcc 的用法
參數 範例 說明
-S gcc -S sum.c -o sum.s 要求 gcc 產生組合語言程式碼
-E gcc -E hello.c -o hello.i 只執行巨集展開,但不產生目的檔
-D gcc -DDEBUG sum.c -o sum 編譯時才定義巨集常數
-g gcc -g sum.c -o sum 編譯時加入除錯資訊,讓 gdb 可遠端除錯
-c gcc -c hello.c -o hello.o 編譯並組譯程式碼,但不做連結
-I gcc -c -I /home/kenny/include -o hello.o 指定引用檔 (*.h) 的路徑
hello.c
-L gcc -L /home/kenny/lib -o hello hello.o 指定函式庫 (*.a) 的路徑

-l gcc -L /home/kenny/lib -lm -lpthread -o 指定函式庫的名稱


hello hello.o
-shared gcc -shared a.o b.o c.o -o libabc.so 產生共享函式庫 (*.so)

-fPIC gcc -g -rdynamic -fPIC -o test 輸出 position-independent code ,一般在輸出動


test.c 態連結函式庫時使用
-Werror gcc -Werror sum.c -o sum.s 將警告視為錯誤,一但有警告就不輸出目標檔

-O0 gcc -S -O0 sum.c -o sum.s 不進行最佳化 ( 預設 )


-O1 gcc -S -O1 sum.c -o sum.s 第 1 級的最佳化 ( 較差 )
-O2 gcc -S -O2 sum.c -o sum.s 第 2 級的最佳化
-O3 gcc -S -O3 sum.c -o sum.s 第 3 級的最佳化 ( 最高等級 )
範例:使用 gcc 進行編譯
C 語言主程式 (main.c) C 語言函數 (sum.c)
#include <stdio.h> int sum(int n) {
int main(void) { int s=0;
int sum1 = sum(10); int i;
printf("sum=%d", sum1); for (i=1; i<=n;i++) {
return 1; s = s + i;
} }
return s;
}

範例 1.1 C 語言程式 - main.c 與 sum.c

gcc main.c sum.c –o sum.o


./sum.o
sum=55

圖 1.6 利用 gcc 同時編譯 main.c 與 sum.c 並輸出


執行檔
範例:使用 gcc 進行組譯
$gcc -S sum.c -o sum.s

$gcc -S main.c -o main.s

$gcc main.s sum.s –o sum2

$./sum2
sum=55

圖 1.7 將 gcc 當成組譯器使用

$gcc main.c sum.s –o sum3

$./sum3

sum=55

圖 1.8 利用 gcc 編譯 C 語言 main.c 同時組譯組合語言 sum.s


1.5.2 微軟 Visual Studio 整合
環境
GNU 工具的優點:

是短小精悍、支援平台眾多、而且開放原始碼

Visual Studio 的優點:

開發環境完整、視覺化開發介面優良、並且與微軟的

Windows 密切整合
Visual Studio
 版本
Visual Studio Professional 版本

Visual Studio Express 版本

 下載點: http://www.microsoft.com/Express/

 分為 Visual C#/Visual C++/Visual Basic/Visual Web Developer


等四個軟體。

 讀者可以下載 Visual C++ 版。


圖 1.9 利用 Visual Studio 編譯與執行
程式
GNU 工具與 Visual Studio 之
比較
GNU 工具的優點:

是短小精悍、支援平台眾多、而且開放原始碼

Visual Studio 的優點:

開發環境完整、視覺化開發介面優良、並且與微軟的

Windows 密切整合
本章摘要 (1)
1.1 系統程式
System Software + System Programming

1.2 電腦的硬體架構
馮紐曼架構
 Computer = CPU+Memory+Bus+Input+Output
 CPU = ALU + 控制單元 + 內部匯流排 + 輸出入

1.3 組合語言
是理解電腦硬體設計的關鍵
多樣、難懂、無法跨平台
本章摘要 (2)
1.4 高階語言
C 語言:是系統程式中最常用的語言

1.5 實務案例
1.5.1 GNU 開發工具
 gcc 的用法

1.5.2 Visual Studio