跳轉到內容

從零開始製作程式語言/決策

來自華夏公益教科書,開放世界開放書籍

你的目標是製作一種程式語言。但是,市場上已經存在許多語言。你製作的語言有什麼目的?其實,主要是語法和輸出程式碼的細微差別造成了各種語言的多樣性。主要是記憶體格式和執行速度。但是,一般來說,這兩者無法兼得。因此,需要做出一些權衡,最終將決定你語言的重要性以及它在全球市場中的地位。有一些細微的因素,比如變數的通用範圍、指令的冗餘、編譯風格和執行速度差異,這些因素乍一看似乎微不足道,但當它們在一份長長的原始碼檔案中累積起來時,它們可以決定程式執行時間是幾分鐘還是幾小時。這些細微因素仍然是不斷研究新穎且更強大的程式語言的驅動力。以下部分將涵蓋你在開始編寫語言之前必須做出的幾個主要決策。

基礎語言

[編輯 | 編輯原始碼]

直接編譯成機器語言非常困難,通常情況下,下一個最好的步驟是使用匯編語言。但是,即使在組合語言中,編譯所需的實際檔案輸入和輸出操作也非常複雜且難以編寫。幸運的是,現在有一些高階語言可以用來編寫我們的編譯器。請注意,基礎語言的選擇對於最終輸出質量並不重要,但對於編譯速度和編譯器編寫難易程度非常重要。這個專案很可能非常耗時,因此必須選擇你感到舒適的語言。

通常情況下,C++ 和 C 等編譯型語言的執行速度比解釋型語言快得多。但是,它們的缺點是可移植性較低,因此基礎語言的選擇完全取決於你的優先順序。

記憶體格式

[編輯 | 編輯原始碼]

如今記憶體容量非常大(通常約為 8 GB RAM),因此可以考慮以前不可想象的預設靜態記憶體佈局格式。在這種格式下,在函式內宣告的變數保持活動狀態,即它們即使在函式返回控制權後,也一直保留其值,直到程式終止。這意味著函式可以更長時間地儲存其值,這是一個重要的因素,可以使程式更加簡短高效。但是,大多數語言都使用所謂的“堆疊”變數,其中變數被推入稱為堆疊的記憶體單元,它們一直保留在那裡,直到函式結束。但是,在它們的壽命結束後,堆疊不會被清除,而是保持原樣,只是現在它可用於覆蓋先前變數的後續變數。但是,這會導致“垃圾值”,從而導致程式錯誤。此外,它需要一個複雜的資料管理系統。但是,堆疊變數佔用的空間更小,訪問速度也更快。此外,還有暫存器變數選項,它們保留在暫存器中,暫存器的訪問速度比堆疊變數快 30 倍。但是,暫存器變數需要非常複雜的資料管理,這會使編譯器更加複雜。

之後,還有彙編中的 .[MODE] 指令選項。這取決於你正在為其編寫編譯器的處理器型別。對於 808386 處理器,使用 .386;對於 808486 處理器,使用 .486,等等。一些組合語言支援同一個處理器的多種模式,但是每種模式最適合其自己的特定處理器。此外,還有 MODEL 指令,即 FLAT 模型、BIG、TINY、LARGE 和 MEDIUM。每個模型最適合其自己的型別。在這本書中,我們使用 FLAT 模型。還取決於作業系統的 MODE。在這裡,我們使用保護模式,它提供了 16 TB(可能因機器而異)的“虛擬記憶體”。

此外,在實際記憶體分配的情況下,分別使用 NEAR 和 FAR 指標用於 NEAR 和 FAR 模型。在保護模式下,作業系統假設 NEAR 模式,因此使用 NEAR 指標。

另一個需要考慮的因素是變數的大小。通常使用三個變數 int、char 和 float。在 32 位環境的 C 編譯器中,int 佔用 4 位元組,char 佔用 1 位元組,float 佔用 8 位元組(對於 double)。還有其他指令 short、long、single 和 double,你可能選擇包含在你的程式語言中,也可能選擇不包含。

大多數彙編器會自行處理記憶體分配,但是對於某些彙編器,你必須更明確地給出精確的指令,說明你希望將變數放在哪裡。

每個語言設計者都知道,如今區分程式語言的最重要因素是執行速度。但是,速度並非易事,如果你想要速度,最好為被稱為最佳化的過程中大量的辛苦付出做好準備。此外,速度往往與記憶體佈局衝突,因此你需要決定哪個對你來說更重要。冗餘是另一個因素,但為了消除冗餘,你需要編寫非常長的演算法來檢查每種冗餘可能性。


Clipboard

待辦事項
新增更多細節和因素


華夏公益教科書