• 沒有找到結果。

第三章 嵌入式符式作業系統的交叉編譯

3.5 系統常用指令

FORTH ENGINE 的終端機介面是一個有效又很簡單的設計。在執行 BYTE_CHANGE 指令時,UART 暫存器中的 LOW_BYTE 送出 8 位元資料,此時 HIGH_BYTE 位元即被移到 UART 暫存器。但我們將 W (0)送入一個正反器,

而這個正反器的輸出直接就連到一個輸出腳位上,此即 FORTH ENGINE 的終 端機輸出埠。

當執行 BYTE_CHANGE 指令時,我們將終端機輸入腳位的狀態鎖入 W(16) , 這是 W 暫存器的溢位元【Carry】,此即終端機的輸入埠了。終端機的輸入 和輸出,即全由 EMIT 及 KEY 來操控。EMIT 及 KEY 用 50us 及 100us 兩個指 令來延遲到 19200 Baud 的半位元及 1 位元的時序。

﹙n1 n2 n3 -- r q﹚算出 n1*n2/n3 最後的餘數 及商。

表 3-9 乘數指令

這是乘法的基本指令,其他乘法指令皆從它衍生而出。FORTH ENGINE 有單步乘法機器碼 MUL。將 W 清作 O,n1 放在 S 內,n2 放在 A 內,重覆執 行 MUL16 次,即可在 T-A 中得到 32 位元的積。

3.5.3 記 憶 指 令

HERE ﹙-- a﹚ 變數,內容為詞典邊界的最高位址。

PAD ﹙-- a﹚ 變數,內容為字串暫存區的位址。

TIB ﹙-- a﹚ 變數,內容為終端機暫存區的位址。

@EXECUTE ﹙a --﹚ 由 a 中取出執行碼欄地址,然後跳到該處去 執行。

CMOVE ﹙a1 a2 n --﹚ 從 a1 搬 n 個 16 位元字碼到 a2 區。

FILL ﹙a n c --﹚ 將 16 位元數值 c 填入 a 起的 n 字碼區。

>CHAR ﹙c -- c﹚ 將不能印出的字符都改為底線符號_,如此為 防止印表機在紙張上印出亂碼。

表 3-10 記憶指令

3.5.4 壓 縮 字 串 及 解 壓 指 令

PACK$ ﹙b n a -- a﹚ 將在 b 位址的 n 個字符壓縮到 a 區,每 2 個 8 位元字符壓縮到一個 16 位元的字碼中,最 後補 0。

UNPACK$ ﹙a b -- b﹚ 將在 a 地址中的一個壓縮後的字串解壓,並 放在 b 區。

表 3-11 壓縮字串及解壓指令

例如 7 個字符的字串「UNPACK$」,未壓縮時是由 8 個 16 位元之字碼組成,

壓縮後成為 2 個字碼,內容如下:

Bit 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 字碼 0 1 0 1 0 1 0 1 0 1 0 0 1 1 1 0 è 'U' 'N'

字碼 0 1 0 0 0 0 0 1 0 1 0 0 0 0 1 1 è 'A' 'C' 字碼 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 è '$' 0

字串壓縮後不但減少了記憶存儲的空間,也顯著地加速了 Forth 系統查字 典的速度。在比對字串時,可一次比較 2 個字符。

3.5.5 數 值 印 出 指 令

FORTH ENGINE 的數值都是以 16 位元方式存在記憶體及暫存器中的,只 有在將數字印出時才須要將其轉成為 ASCII 字串,每字符 8 位元。轉換時 用 BASE 裡所存數值作轉換的基數。所以可以很方便地把數值隨時轉成以十 進制,十六進制,或其他基數的字串形式印出。

數字列印的指令常用的有以下幾個:

. ﹙n--﹚ 將 n 轉換成字串顯示在終端機上。

U. ﹙u--﹚ 將自然數 u 顯示在終端機上。

.R ﹙n1 n2 -- ﹚ 將 n1 顯示在 n2 欄位中,靠右對齊。

U.R ﹙u n --﹚ 將 n1 顯示在 n2 欄位中,靠右對齊。

? ﹙u n --﹚ 將自然數 u 顯示在 n 欄位中,靠右對齊。將 a 地 址中的數值取出,顯示在終端機上。

HEX ﹙--﹚ 將 BASE 基數改為 16,以後數字轉換即十六進制。

DECIMAL ﹙--﹚ 將 BASE 基數改為 10,以後數字 轉換即十進制。

表 3-12 數值印出指令

為要完成以上數值列印的功能,FORTH ENGINE 須要有一系列的支援指令。

使用者也可以自行利用這些指令,設計出更適合特殊不同場合應用的列印 指令。

str ﹙n -- b u﹚ 將數值 n 轉換成字串儲存在 b 區,字串長度是 u。

DIGIT ﹙u -- c﹚ 將一位數的值 u 轉換成其對應的 ASCII 數碼 c。

EXTRACT ﹙n1 base -- n2 c﹚

以基數 BASE 去除 n1,餘數轉成一位的數碼 c,留 下商數 n2,以便繼續數值轉換之程序。

<# ﹙--﹚ 準備轉換,設定 PAD 存所得字串,以 HLD 為指標。

HOLD ﹙c --﹚ 將一位數碼 c 寫到 HLD 所指的位置,並將 HLD 減 1,準備接受下一數碼。

# ﹙u1 -- u2﹚ 由 u1 中轉出一位數碼寫到 PAD 中,商是 u2。

#S ﹙u --o﹚ 將 u 轉出所有數碼字串寫到 PAD 中,最後商是 0。

SIGN﹙n --﹚ 若 n 小於零,則在數碼字串前加負 號。

#> ﹙u1 -- b u2﹚ 丟掉 u1,留下數碼字串的地址 b 及其長度 u2。

表 3-13 列印指令

3.5.6 數 值 輸 入 指 令

由終端機輸入的數字都是 ASCII 數碼字串,須要轉換成對應的 16 位元 數值才能放在堆疊上運用,或是存在記憶體中。將數碼字串轉換成數值的 指令是:

NUMBER? ﹙ a -- n -1 | a 0 ﹚

將在位址 a 的數碼字串轉換成 16 位元的數值 n 及-1 的旗號。若轉換不成功,(字串中有非數字

a 0 ﹚ 碼的符號),則保留地址 a 並留下 0 的旗號。

DIGITS ﹙ c base -- u f ﹚

將一位數碼字符 c 按基數 BASE 轉為數值 u 及 -1,若 c 不是數碼,則保留 c 並留下 0 的旗號。

表 3-14 數值輸入指令

3.5.7 其 他 列 印 指 令

除了列印數值字串外,FORTH ENGINE 也提供一套相當完整的指令,讓 使用者很方便地在終端機上顯示各樣文字資料,排列成整齊美觀的文件,

這套指令是:

SPACE ﹙--﹚ 輸出一個空格。

CR ﹙--﹚ 換行。

CHARS ﹙n c --﹚ 輸出 n 個 ASCII 碼 c 所對應的字符。

TYPE ﹙a u --﹚ 從地址 a 取 u 個 ASCII 碼字符輸出。

Do$ ﹙-- a﹚ 將編碼在程式中的字串解壓縮到 TEXT 區,並將 TEXT 區的地址 a 放上堆疊。 $"| ﹙-- a﹚ 將編 碼在此指令後的字串解壓,存到 a 區。

." | ﹙--﹚ 將編碼在此指令後的字串解壓,並印出。

表 3-15 其他列印指令

相關文件