a24fa07de0894b8eb294746c991a0099.ppt
- Количество слайдов: 96
資電學院 計算機概論 F 7810 第八章 系統程式 陳邦治編著 旗標出版社
本章重點 l l 2 電腦系統是由硬體及軟體所組成 軟體可分為系統程式 (或稱為系統軟體 )與 應用程式 (或稱為應用軟體 )二類 本章將介紹系統程式中較具代表性的軟體 由於作業系統將在第九章介紹,因此本章 的介紹不包括作業系統
大綱 l l l 3 電腦軟體分類 組譯程式 巨集處理程式 前置處理程式 連結載入程式 編譯程式
電腦軟體分類 l l 電腦系統是由硬體及軟體所組成 軟體可分為 – – l 4 應用軟體 (application software) 系統軟體 (system software) 應用軟體是為了處理某個特定的問題而撰 寫的程式,應用軟體也可稱為應用程式 (application program)
應用軟體基本定義 l l 應用軟體是為了處理某個特定的問題而撰 寫的程式,應用軟體也可稱為應用程式 (application program) 常用的應用軟體有二類 ,分別是: – 市售套裝軟體 l – 5 如電腦遊戲軟體、文書處理軟體及多媒體軟體等等 使用者自行撰寫的程式
系統軟體基本定義 l 系統軟體是指電腦系統為維特正常運作或 開發應用程式所不可缺少的軟體 – l 6 如作業系統 (Operating System; OS)、組譯程式 (assembler)、編譯程式 (compiler)、直譯程式 (interpreter)、載入程式 (loader)、連結程式 (linker)、 巨集處理程式 (macro processor)、前置處理器 (preprocessor)及公用程式 (utility)等軟體 系統軟體有時也可稱為系統程式 program) (system
應用軟體 l l 市售套裝軟體是最常用的應用軟體 常見的套裝軟體有 – 7 「文書處理軟體」、「電子試算表軟體」、「簡報軟 體」、「繪圖及影像管理軟體」、「多媒體軟體」、「 通訊軟體」及「資料庫管理系統」等,下表為常用 的套裝軟體的細部分類及範例
套裝軟體的細部分類及範例 8
套裝軟體的細部分類及範例 9 (cont. )
常用的系統軟體的功能及範例 10
常用的系統軟體的功能及範例 (cont. ) 11
組譯程式 (assembler) l l 12 組譯程式的功能是將組合語言寫成的原始 程式翻譯成目的碼 組譯程式功能圖 組合語言程式是由指令及資料組成。常用的指令有二種,分別是機器 指令 (machine instruction)與虛擬指令 (pseudo instruction)。機器指令經由 組譯程式處理後會產生目的碼;虛擬指令的主要作用是標明程式的開 始處及結束處,或給予組譯程式指引,因此虛擬指令經由組譯程式處 理後通常不會產生目的碼
組譯程式的 作及輸出 l 組譯程式應執行的 作有以下 – – – 13 5項 將機器指令轉換成相對應的機器碼 將符號運算元 (symbolic operand)轉換成相對應的 機器位址 以機器所能接受的格式產生機器指令 將資料常數 (constant)轉換成機器內部的表示法 產生的目的碼 (object code)及組合程式列表
目的碼之基本內容 l 組譯程式處理完原始程式碼後將產生目的碼,而 目的碼之基本內容應有以下三種 – 標頭記錄 (head record) l – 本文記錄 (text record) l – 記載程式的內容,包括指令的機器碼,欲載入的位址及資料 結束記錄 (end record) l 14 記載程式的名稱,程式的起始位址以及程式的長度等三種 資訊 記載程式的結束處 , 並指定程式第一個開始執行的指令的 位址
組譯程式的分類 l 組譯程式依不同的處理方式,通常可以分 為三類 – – – 15 單次處理組譯程式 兩次處理組譯程式 多次處理組譯程式
單次處理組譯程式 (single pass assembler) l l 處理原始程式碼一次並產生的目的碼 單次處理組譯程式允許「後方參考」 (backward reference),但不允許「前方參考」 (forward reference) 動作 – l 16 「後方參考」指符號先定義,才引用,而「前方參考」則是 指符號未定義前就先引用 單次處理組譯程式處理方式如下圖
單次處理組譯程式 (cont. ) l l 17 因為單次處理組譯程式只掃瞄原始程式碼 一次,因此組譯 (assemble)時間在三種組譯 程式中最短 因目的碼未執行最佳化處理 (optimization), 執行效率可能稍差
單次處理組譯程式 範例 l 18 解: AX、 BX、 CX及 DX為暫存器名稱,因此可直接引用不需定義。此程式段中定 義的符號共有三個,分別是 LOOP、 DATA及 SIX,因此僅需針對此三個符號 說明即可 (1)「 backward reference」指令: LOOP JMP (2)「 forward reference」指令: BX, SIX及 MOV DX, DATA SUB
兩次處理組譯程式 (two pass assembler) l l 19 兩次處理組譯程式的程式結構分為二個部份,分別是 Pass 1 與 Pass 2 先由 Pass 1處理原始程式後,輸出「中間碼」, Pass 2再處理「中 間碼」後輸出目的碼 (請注意:不是處理原始程式二次 ) Pass 1的 作為定義符號 (define symbol),而Pass 2的 作則為 產生目的程式 (generate object code) 兩次處理組譯程式處理方式如下圖 兩次處理組譯程式允許「前方參考」,通常不會對目的碼執 行最佳化處理,因此執行效率可能稍差
多次處理組譯程式 (multiple pass assembler) l l 20 多次處理組譯程式會作多次掃瞄的動作,因此允 許「前方參考」 在第一次處理時先保留這些牽涉到「前方參考」的 未定義符號,在往後的幾次處理中再一一的對這 些符號作處理 可對目的碼執行最佳化處理,因此執行效率較佳 因多次處理組譯程式會掃瞄程式碼多次,因此組 譯時間在三種組譯程式中最長
多次處理組譯程式 範例 l l 21 請說明以下程式段為何需要三次處理的組譯程式 才能處理? A EQU B+1 B EQU C+100 C EQU 200 解: Pass 1: 定義 C的值為 200 Pass 2: 定義 B的值與 C+100相同 Pass 3: 定義 A的值與 B+1相同並產生目的碼
絕對程式 (absolute program) l l 22 「絕對程式」 (absolute program)是指必須載入到使用者指定的 位址才能執行的程式 事實上在同一時刻可能同時會有多個程式在記憶體中由於 無法預知這些程式執行的順序,因此無法事先分配程式所 實際佔用的記憶體空間 因為程式在執行過程中可能因為本身之需求或其他程式之 需求而必須將程式碼由目前所佔用的記憶體空間,搬移到 另一個記憶體空間來執行 基於以上二個原因,可以瞭解「絕對程式」的觀念有嚴重的缺 點為滿足程式執行時的實際需求,必須有一種作法可以允 許程式能載入不同於原先載入的位址,這種可將程式載入 不同於原先載入的位址的動作稱為「重定位」 (relocation)
程式重定位 l l l 為了滿足「重定位」之需求,組譯程式輸出之目的碼中應提供 資訊給載入程式,再由載入程式來執行修正位址的動作 目的碼中若包含程式載入記憶體時應修改的資料,此種目的 碼便稱為「可重定址程式」 (relocatable program) 為了提供目的碼「重定位」能力,組譯程式會在目的碼中多輸 出一項稱為修飾記錄 (modification record)的資料,修飾記錄內 記載了目的碼在載入記憶體時需修改的資訊 – l 23 修飾記錄的內容包含了必須被修改的位址欄位之起始位址及被 修改的欄位的長度 假設程式中有 goto 敘述。若程式提供「重定位」功能,則goto 敘述後方所指定的敘述之位址便必須隨著程式載入位址的 不同而連帶被更改
覆疊結構 (overlay structure) l l 「覆疊結構」是指將程式中不會同時執行的 部份載入到記憶體中相同的位置執行 兩次處理組譯程式中的 Pass 1與 Pass 2,因為 先執行 Pass 1,再執行Pass 2,滿足「不會同 時執行」的條件 – 24 可讓組譯程式的 Pass 1與 Pass 2使用相同的記憶 體空間來執行,如此一來便可降低兩次處理組 譯程式執行時記憶體空間的需求量
具有覆疊結構的兩次處理組譯程式 25
常見定址模式 l l 不同的定址模式提供了取得運算元內容的 不同方法 常見定址模式可分為 – 26 「立即定址模式」、「直接定址模式」、「間接定址 模式」、「索引定址模式」、「基底定址模式」及「 相對定址模式」六種
立即定址模式 (immediate addressing mode) l 立即定址模式是指運算元為指令的一部份, 執行時不必再做額外的記憶體存取動作可 立即利用運算元的值作運算 – 27 如「 move AX, 13 H」指令運算元的值為 13 H(16進位 的 13),不必再做額外的記憶體存取動作
直接定址模式 (direct addressing mode) l 28 直接定址模式代表指令中運算元之值為資 料存放在記憶體中的位址,必須透過此位 址作一次記憶體存取的動作才能取得所需 的資料,又稱為絕對位址模式 (absolute addressing mode)
間接定址模式 (indirect addressing mode) l 29 間接定址模式是指運算元欄內的值是位址, 此位址會指向記憶體中之位置,此位置中 存放資料在記憶體中的位址
索引定址模式 (index addressing mode) l 30 索引定址模式是指將運算元欄位的值加上 索引暫存器 (index register)之值即為資料的 位址。若要變更存取記憶體中的位置則需 變更索引暫存器之值
基底定址模式 (base addressing mode) l 31 基底定址模式是指將運算元欄位的值加上 基底暫存器 (base register)的值,即為資料的 位址。若要變更存取記憶體中的位置則需 變更運算元碼之值
相對定址模式 (relative addressing mode) l 32 相對定址模式是指將運算元欄位的值加上 程式計數器 (program counter)內的值,即為資 料的位址
巨集處理程式 l 設計程式時,經常會將一些相關的敘述集 合在一起以節省程式設計的時間,常使用 的方式有 – – – l 33 迴圈 (loop) 副程式 (subroutine) 巨集 (macro) 迴圈及副程式的觀念請參考本書「程式設 計篇」中之介紹,此處僅介紹巨集
巨集相關觀念 l l l 34 巨集又稱為「巨集指令」(macro instruction),用來代表程式中一 群常用的敘述 「巨集定義」 (macro definition)的功用是定義巨集及其所對應的 一群敘述 「巨集展開」 (macro expanding)又稱為「巨集呼叫」(macro call), 是指將巨集名稱以相對應的一群敘述取代 程式中的「巨集定義」程式段可利用「巨集呼叫」來呼叫 當語言處理器處理「巨集呼叫」敘述時會利用「巨集展開」的 動作以「巨集定義」來取代「巨集呼叫」敘述
「巨集展開」示意圖 35
巨集範例 XXX MACRO &參數 巨集程式碼 MEND l 「 XXX」表示巨集名稱 l 「巨集程式碼」以「 XXX」代表其名稱,必須透過「 XXX」巨集名 稱來呼叫巨集 l 當程式經由巨集處理程式處理後,巨集處理程式會將程式中 所有的巨集名稱替換成相對應的巨集定義內容,因此程式經 過巨集處理程式處理後的程式碼將會變長 l 因為巨集的處理模式是用「字串替代」方式 (將一條敘述替換 成一段敘述群 ) l 完成巨集處理的程式碼執行時,不會有控制流程 (control flow) 的轉移,因此執行的速度會比利用副程式設計程式快 36
巨集範例 37
巨集與副程式的比較 38
巨集的優點 l 使用巨集指令的優點有以下三項 – – – 39 程式較易維護 程式較易除錯 系統較具彈性
C++語言的 inline函式 l l l 40 在某些知名的近代高階語言也提供了巨集 處理的功能,如 C++語言 在 C++語言中提供的「 inline函式」便是利用 了巨集處理的觀念 「 inline函式」的作 法是在函式的名稱前加上 「 inline」關鍵字便可讓此函式成為「 inline函 式」
C++「 inline函式」處理模式 41
精選範 例 l l 42 單次處理組譯程式通常需要建立「未定義符號表」,假如不允許建立「未定 義符號表」,則在下列五種情形的不同組合下各需幾道組譯器 : (a) 符號在用到時已定義。 (b) 符號在用到時未定義。 (c) 所有巨集指令呼叫均在巨集指令定義之後。 (d) 巨集指令呼叫可以在巨集指令定義之前。 (e) EQU 敘述內含有未定義符號。 如 AC EQU BASE-1 BASE EQU 15 (A) (a)+ (c) (B) (b)+ (c) (C) (a)+ (d) (D) (b)+ (d) (E) (b)+ (c)+ (e) (F) (b)+ (d)+ (e) 解: 處理巨集的問題主要分為二個部份,一為巨集定義,另一則為巨集展開
(A) (a) 符號在用到時已定義 (c) 所有巨集指令呼叫均在巨集指令定義之後 (A)單次處理組譯程式 因為符號及巨集指令均在用到或呼叫時已事先定義好,因此僅需一 次處理便可完成所有的 作。執行 作如下: Pass 1:巨集定義、巨集展開、符號定義、產生目的碼。 43
(B) (b) 符號在用到時未定義。 (c) 所有巨集指令呼叫均在巨集指令定義 之後 (B)二次處理組譯程式 由於符號在用到時尚未定義,故需二次處理組譯程式 方可處理完成。執行 作分配如下: Pass 1:巨集定義、巨集展開、符號定義。 Pass 2:產生目的碼。 44
(C) (a) 符號在用到時已定義。 (d) 巨集指令呼叫可以在巨集指令定義之 前 (C)二次處理組譯程式 因為 Pass 1 處理符號及巨集的定義,但由於巨集指令 的呼叫可在巨集指令定義之前,因此 Pass 1 無法完成 組譯 作,故需 2 個 pass 才足夠。執行 作分配如下: Pass 1:巨集定義。 Pass 2:巨集展開、符號定義、產生目的碼 45
(D) (b) 符號在用到時未定義 (d) 巨集指令呼叫可以在巨集指令定義之 前 (D)三次處理組譯程式 (b)符號在用到時未定義:二次處理。 (d)巨集指令呼叫可在巨集指令定義之前:二次處理。 巨集展開與符號定義可合併由一個 pass 來處理。故共需 3個 pass 來完成這項 作。執行 作分配如下: Pass 1:巨集定義。 Pass 2:巨集展開、符號定義。 Pass 3:產生目的碼 46
(E) (b) 符號在用到時未定義 (c) 所有巨集指令呼叫均在巨集指令定義之後 (e) EQU 敘述內含有未定義符號 (E)三次處理組譯程式 執行 作分配如下: Pass 1:巨集定義、巨集展開、符號定義 (含第一層 EQU符號定義 ) Pass 2:繼續處理第二層 EQU符號定義 Pass 3:產生目的碼 47
(F) (b) 符號在用到時未定義 (d) 巨集指令呼叫可以在巨集指令定義之前 (e) EQU 敘述內含有未定義符號 (F)四次處理組譯程式 執行 作分配如下: Pass 1:巨集定義 Pass 2:巨集展開、符號定義(含第一層 EQU符號定義 ) Pass 3:繼續處理第二層 EQU符號定義 Pass 4:產生目的碼 48
前置處理程式 l l l 49 「前置處理程式」是指程式語言處理器在開 始處理程式段之前的處理程式 本節將以 C程式語言為例,說明「前置處理 程式」之作法 對一個 C 程式而言,程式在被編譯之前, 程式會先由 C程式語言的「前置處理程式」 先負責處理含有「 #」開頭的敘述後 (如 #include 、 #define等 ),再將結果檔交由編譯 程式處理後續 作
C 語言前置處理程式處理流程圖 50
前置處理程式範例 利用 C語言定義一敘述如下: #define square(x) x*x square(x)的用途為傳回 x的平方值 (如 執行 square(7),執行結果為 49),若x 為 4+3則執行結果為何? 解: 19 C語言處理此類問題時,不會先行計 算 4+3= 7之結果,再將 7傳入 square(x)中計算,而是直接將 4+3傳 入,因此實際計算過程如右 51
連結載入程式 l l l 52 當原始程式經過程式語言處理器處理後 (編 譯或組譯 ),再經連結 (linking)成可執行的程 式碼後,最後便必須被「載入」主記憶體中 等候執行 此處所指的「載入」 作便是由載入程式所 負責 因此載入程式所負責的 作是將程式碼由 輔助記憶體載入主記憶體中等候執行
載入程式的 作 l 配置記憶體空間 (allocation) – – l l 要求作業系統配置空間供程式載入使用。 解決不同程式段之間彼此相互參考的問題,即解決「外部 符號」 (external symbol)的引用問題。「外部符號」是指不在 本地程式段內定義之符號。 連結 (linking) 重定址 (relocation) – l 載入 (loading) – 53 調整目的程式中與記憶體相關的指令或資料使程式能載 入不同於原先載入的位置。 將程式載入主記憶體中 注意:只要能夠完成上述第四項「載入」 作之程式,便是載入程式; 並不是所有的載入程式都能完成以上四項 作
載入程式的分類 l 載入程式的種類很多,依其功能及特性的 不同可分為四種 – – 54 「絕對載入程式」 (absolute loader) 「組譯並執行載入程式」(assemble-and-go loader) 「可重定址載入程式」(relocatable loader) 「連結編輯程式」 (linkage editor)
絕對載入程式 l 「絕對載入程式」僅負責載入 作,另外三項 作 負責單位如下: – – – l l 55 配置記憶體空間:程式設計師。 連結:程式設計師。 重定址:組譯程式。 因為程式設計師必須負責配置記憶體空間及連結 二項 作,因此對程式設計師而言具有較大的自 主權;但相對地,程式設計師必須牢記副程式的位 址及安排目的碼的載入位址,所以負擔很大 「絕對載入程式」無法自行處理重定位問題
組譯並執行載入程式 l l l 56 此類載入程式為直譯式作法 當原始程式被翻譯成機器語言後就直接被 放置在主記憶體內,待原始程式全部翻譯 完成,便馬上開始程式的執行動作 若採用「組譯並執行載入程式」,當程式要 執行時,每次都必須重新翻譯,因此執行 效率較差
可重定址載入程式 l 57 此類載入程式允許程式段可調整載入記憶 體中之位址
連結編輯程式 l l l 58 對不同程式段合併執行連結 (linking)動作並 產生產生「已連結程式」(linked program)或稱 為「載入模組」 (load module) 當程式執行時才處理重定址及載入 作 具有較佳的執行效率之特性
範例 「絕對載入程式」如何處理「重定位」問題? l 解: 必須透過組譯程式重新翻譯原始程式碼, 才可處理「重定位」問題 l 59
連結程式 l 連結程式 (linker)的 作是解決不同程式段間彼此相互參考 的問題 – l l l 60 就是解決「外部符號」的參考問題 「外部符號」指的是不在本地定義的符號,可能是函式庫 (library)內的函式,或是其他程式段內定義的函式或符號 連結程式會將程式中所使用到外部符號連結起來,並產生完 整的執行檔 假設程式由多人分 合作完成,此時參與程式開發 作的程 式設計師可各別完成自己的程式段,每個原始程式都可個 別編譯 (separate compile)成目的碼,然後再利用連結程式將這 些目的檔連結合併成一個完整的執行檔
連結程式處理流程 61
動態載入 (dynamic loading) l l l 62 「動態載入」是指將程式的載入的動作,延 遲到程式執行的時候才處理 真正會被執行到的程式才做載入的動作 「動態載入」可利用覆疊(overlay)及虛擬記憶 體 (virtual memory)技術來達成
動態連結 (dynamic linking) l l l 63 動態連結是指將連結的動作,延遲到程式 執行時才處理 真正會被執行到的程式段才執行連結處理 動作 程式在執行過程中,可能有部份的符號或 副程式並不會被引用或呼叫,因此如果在 連結時便將這些未被引用或呼叫的符號或 副程式連結進來,將增加連結程式的負擔, 同時也增加了記憶體空間的需求量
範例 若系統採用「動態連結」機制,當副程式執行完畢時,其控制 流程的轉移方式,與一般副程式呼叫後控制流程的轉移方 式是否相同? l 解:不同 「動態連結」實作機制如下: l – – 首先,程式提出一個系統呼叫給作業系統並將副程式的名稱傳 給作業系統,然後程式的控制權將轉移給作業系統 接下來,作業系統將檢查此副程式是否已經在記憶體中 l l 64 若副程式已在記憶體中則直接開始副程式之執行,待副程式執行 完畢,程式控制權必須交還給作業系統,再由作業系統將控制權交 還給程式 若副程式不在記憶體中,便必須由動態連結程式庫 (dynamic link library)中將副程式連結並載入主記憶體中。待副程式載入主記憶體 後,開始副程式之執行,當副程式執行完畢時,程式控制權必須交 還給作業系統,再由作業系統將控制權交還給程式
「動態連結」實作機制 65
範例 請說明「組合語言」、「組譯程式」與「連結載入程式」 (linking loader)三者之 間如何完成「符號連結」 作 (symbolic linking)。 解: 「符號連結」是指解決外部符號參考的問題。 組合語言利用「 EXTDEF」及「 EXTREF」指令來指定變數的類別,並將資訊 提供給組譯程式。 如以下範例: EXTDEF A, B, C // 代表 A, B, C三個變數在本地定義,但可被外部程式段 引用。 EXTREF D, E // 代表 E, F二個變數不在本地定義,但可引用。 66 組譯程式必須將程式中宣告為「 EXTDEF」及「 EXTREF」型態的變數特別 記錄下來,並將資料提供給連結載入程式做為符號連結 作使用。
編譯程式 (compiler) l l l 67 編譯程式的作用是將利用高階語言寫成的原始程 式 (source program)翻譯成目的碼 (object code) 編譯程式會對原始程式碼中的每一條敘述,按照 先後順序均做一次之轉換處理,並產生對應之目 的碼,這種轉換處理的 作必須完全遵守採用的 程式語言所規定的文法規則 (grammar rules) 不同程式語言的文法規則是不相同的。若撰寫程 式時違背了程式語言的文法規則,編譯時將會發 生文法錯誤之訊息
文法四要素 l 文法 (grammar)是由四個要素所構成 – – 68 分別為終端符號 (terminal symbol,簡寫為「 ), T」 非終端符號 (non-terminal symbol,簡寫為「 ), N」 起始符號 (starting symbol,簡寫為「 )與文法產 S」 生規則 (production rule,簡寫為「 ) P」 終端符號表示不能再以其他符號來替代。非終 端符號表示可以再以其他符號來替代 N與 T須滿足以下的關係: N∩T = 從事文法推演之步驟由 S開始且 S N
文法產生規則須符合條件 l 文法產生規則須符合下列條件: – – u→v P,其中u (N T)+且 v (N T)* 其中 l l 69 (N T) +:代表由非終端符號與終端符號所組成的任意 長度之字串,但不得為空字串 (N T)* :代表由非終端符號與終端符號所組成的任意 長度之字串。
範例 70 範例: 若 T={a}, N={A},請說明(N T)+及 (N T)*的結果值為 何? 解: (N T)+ 的結果值如下: {a, A, aa, a. A, Aa, AA, aaa, aa. A, a. Aa, a. AA, Aaa, Aa. A, AAa, AAA, …. . }共有無限多種可能。 (N T)* 的結果值如下: {λ, a, A, aa, a. A, Aa, AA, aaa, aa. A, a. Aa, a. AA, Aaa, Aa. A, AAa, AAA, …. . }共有無限多種可能,其中「 λ」代表空 字串
文法的分類 (1/3) l Type 0: 無任何限制。 Type 0文法所產生之 Language可利用 Turing Machine辨識。 l Type 1: 與上下文相關的文法 (context-sensitive grammar),其文法產生 規則必須滿足以下規則: u→v P , |u| |v| Type 1文法所產生之 Language可利用線性限制自動機 (Linear Bounded Automata)辨識且規定文法產生規則左方的 符號長度不得大於右方的符號長度 71
文法的分類 (2/3) l Type 2: 與上下文無關的文法 (context free grammar),又稱為BNF文法 文法產生規則必須滿足以下規則: u→v P,其中u N, v (N T)* -λ Type 2文法所產生之 Language可利用推壓自動機 (Push Down Automata)辨識且規定文法產生規則左方僅允許長 度為 1之非終端符號 72
文法的分類 (3/3) Type 3:正規文法(regular grammar) Type 3文法所產生之 Language可利用有限狀態自動機 (Finite State Automata)辨識且規定文法產生規則左方僅允許長度為 1之非終 端符號,而文法產生規則右方則僅允許長度為 1之終端符號 正規文法又分為二類: (1)右線性正規文法 (right linear regular grammar)其文法產生規則 需滿足以下規則: A→u. B or A→u,其中A, B N, u T 73 (2)左線性正規文法 (left linear regular grammar)其文法產生規則需 滿足以下規則: A→Bu or A→u,其中A, B N, u T
BNF文法 l l 74 由於近代高階語言的文法多採 BNF文法來 描述,因此本節將針對 BNF文法之特性與 作法做介紹 BNF文法常用的符號整理如下表
範例 若有一個 BNF文法規則定義如下: <A>: : = <A> + <A>|<A> - <A>|<A> * <A>|<A> / <A>|id 請根據以上的文法規則,推導出 id*id+id/id 。 解: 根據題目的文法規則, id*id+id/id的推導過程如下: 75
剖析樹 l l 76 剖析樹是根 據語言的 B. N. F. 描述, 將敘述轉換 成相對應的 樹狀結構,此 樹狀結構被 稱為剖析樹。 剖析樹會比 文法推導式 具備較高的 可讀性及較 易理解 利用上例來 說明,對應的 剖析樹產生 過程如右圖 所示
模擬兩可的文法 (ambiguous grammar) l 「模擬兩可的文法」 – – l 「模擬兩可的文法」正式的定義如下: – 77 「混淆的文法」或「曖昧的文法」 文法定義不完備,可能導致程式執行結果不唯 一 根據語言的 B. N. F. 描述,對同一敘述可繪出二 個或二個以上不同的剖析樹,則稱此語言的文 法是模擬兩可的
範例 以前題為例, id*id+id/id的另一 推導過程如下: <A> : : = <A> * <A> : : = id * <A> + <A> : : = id * id + <A> / <A> : : = id * id + id / id 78 對「 id*id+id/id」敘述而言,根據<A>: : = <A> + <A>|<A> - <A>|<A> * <A>|<A> / <A>|id文法規則可繪出以上二種不同的剖析樹,所以此文法規則為模擬兩可 的文法
編譯程式的 作 l l 編譯程式的功能是處理高階語言寫成的原 始程式,並產生可在機器上執行的目的碼 編譯程式主要的 作依序可分為 – 79 「語彙分析」 (lexical analysis)、「語法分析」 (syntax analysis)、「語意分析」 (semantic analysis)、產生「中 間碼」 (intermediate form generate)、「最佳化」 (optimization)及「目的碼產生」 (object code generate) 共六個階段
語彙分析 l l l 利用語彙分析器 (lexical analyzer),處理原始 程式進行語彙分析 作 語彙分析是指將原始程式的內容切割成文 法基本元素「token」 以 C語言之敘述「a=b+c; 」為例 – 80 「 a=b+c; 」敘述共可切割成 6個 tokens,分別是「 a」、 「 =」、「 +」、「 ; 」 b」、「 c」及「
語法分析 l l 81 利用語法分析器 (syntax analyzer),進行語法 分析 作 語法分析是指根據文法產生規則,將 token 組合成剖析樹
語意分析 l l 82 利用語意分析器 (semantic analyzer),進行語 意分析 作 語意分析是指根據剖析樹判斷敘述是否合 乎語意規定並轉換成動作表 (action list)
產生中間碼 l 83 把動作表轉換成中間碼
最佳化 l 84 對中間碼執行「與機器無關最佳化」 作
目的碼產生 l 85 依據最佳化的中間碼產生目的碼
編譯程式最佳化 l 編譯程式執行最佳化動作的目的是為了加 快執行的速度,而最佳化動作可分為二大 類 – – 86 「與機器無關最佳化」(machine independent optimization) 「與機器相關最佳化」(machine dependent optimization)
與機器無關最佳化 l l 87 將迴圈中不變的運算式或值移到迴圈外 編譯時期計算 (compile time computation) 簡化共同的子運算式 (sub-expression) 捷徑計算 (short circuit evaluation)
將迴圈中不變的運算式或值移到迴圈外 s=0; for (i=1; i<=100; i++) { s = s+i; a=5; } 可最佳化為以下程式段: s=0; a=5; for (i=1; i<=100; i++) s = s+i; 88
編譯時期計算 若程式中的運算式中有部份運算的值可先 在編譯時期計算,就不須等到執行時才計 算 例如, s = (x+4*6/3)/y; 可最佳化為以下程式段: s = (x+8)/y; 89
簡化共同的子運算式 例如, x = a*b+c*d-e; y = c*d+a*b-f+g; 可最佳化為以下程式段: u = a*b; v=c*d; x = u+v-e; y = v+u-f+g; 90
捷徑計算是指對運算式 (通常是指布林運算式 )作求 值動作時,無需做完整個運算式即可得出最後的結 果。 例如, X 1 and X 2: 若 X 1為 false則運算式的結果為 false,不需再計算此 運算式中 X 2 之值即可決定最後的結果值。 X 1 or X 2: 只要 X 1為 true則運算式的結果為 true,不需再計算此 運算式中 X 2 之值即可決定最後的結果值 91
與機器相關最佳化 l 與機器相關最佳化可分為 – – – 92 3種不同的作法 去除多餘的 (redundent)指令碼 調整指令執行的順序 多使用暫存器 (register)存放變數
去除多餘的指令碼 將程式中多餘的指令碼去除 例如, ……… MOV AX, BX MOV AX, CX ……… 可最佳化為: ……… MOV AX, CX ……… 93
調整指令執行的順序 例如, ……… MUL BX, AX MUL CX, AX ADD BX, CX ……… 可最佳化為: ……… ADD BX, CX MUL BX, AX 94
編譯程式的編譯程式 (Compiler’s compiler) l 95 編譯程式的編譯程式是指利用程式語言自 己的語法來撰寫自己的編譯程式
範例 l l l 96 假設有一個 C語言的子集合 X語言,X語言除了不 具備 for-loop、 while-loop及 do while- loop三種迴圈結 構之功能外,其餘的功能、指令、提供的資料型態 或語法等規定均與 C語言相同 我們可先針對 X語言設計出 X語言的編譯程式,再 利用 X語言之語法來設計 C語言的編譯程式 由於 X語言本身為 C語言的子集合,因此利用 X語 言之語法來設計 C語言的編譯程式相當於利用 C語 言之語法來設計 C語言的編譯程式
a24fa07de0894b8eb294746c991a0099.ppt