2018年12月21日 星期五

如何在Flash ROM上實現直譯語言3: Forth系統分析

LBForth和一般Forth不同,因為它不用從CPU指令來建造,所以沒有基本指令再堆積成高階功能的問題。
因為由C建造,所以它只要專心應付語言實現問題。這使得系統簡單不少。

所以只要看幾個大的函式,弄清其功能,就可以知道如何動作。
但在解析前,有一個必須解決的問題,它的字典資料結構要先弄清楚。
因為這個是Forth運行最重要的結構。

字典的主要內容:
1.字名(函式名): 輸入的文字代表
2.內容(執行欄): op code或是指標,op code是基本執行功能。高階字以指標表代,遇到指標會跳去對應的記憶體內容再解析,直到執行op code。
3 .結構串接: 以link-list串起來
4. 屬性及標記,後面用到時再分析
實際排列:有固定長度的放在前面,所以link-list為第一個word,第二個是屬性,和名字共用32個byte(佔4個word),接下來是執行欄,長度不定。

字典在程式碼內是看不到的,因為它是在執行才生成,這個動作有利於Flash的寫入,也是可以利用未用的程式Flash的原因。個人覺得這個設計解決MCU上可以動態增加函式的方法。

再來是Forth的執行結構,它和CPU設計有相關,所以很像硬體的方式。
主要有二個堆疊,一個是資料堆,所以資料及參數全部放在此運算。
另外是一個返回堆,主要是呼叫返回堆疊及一些控制結構變數也放在內。
二個堆疊各有一個管理指標暫存器。
另外在執行上,有一個指令指標暫存器(IP)用來標記目前執行位址。

使用二個堆疊原因:
資料處理全部在資料堆疊上,故使用者要去做堆疊內容管理,這個在高階電腦語言是沒有的。因為此動作沒有執行效果,但可以限定RAM的使用只在資料堆疊上。這也是為何Forth使用RAM很少就可以運作。
MCU一向RAM就是不多,其他語言都有RAM需求問題,若是RAM大,MCU就不用寫得辛苦了。

實際上執行,有分成直譯模式及編譯模式。
平時在直譯模式下,輸入一個字串結束(空白字元出現),就去字典查找這個字,有找到,就依執行欄內容再進一步查找或是執行。
若是直譯失敗,再來是進行數字解析,因為這個字串有可能是數字字串,解析成功,就放入資料堆。
若再次直譯失敗,就沒法了,就執行錯誤處理(顯示輸入錯誤)。
有多字輸入下,會一個一個去執行,直到沒有新的輸入。
但有個直譯指令是不一樣的,它會進入編譯模式。
編譯模式下一樣有找字和轉換數字字串的動作,但再下去的動作不同,它不執行而是寫入Flash,生成新的字進入字典內。
在編譯模式下,一樣找字,找到字就將其執行欄位址寫入新字的內容,然後找下一個字。遇到數字時有點不一樣,會先寫入一個lit指令碼再寫入資料值。執行到lit指令碼會將下一欄的內容吐回資料堆疊。這樣就完成固定值的編譯。

了解Forth的運作後,才能做下一步的修改。

沒有留言:

張貼留言