分類彙整: 樹莓派之編程

CPU 機器語言的『解譯器』

電腦裡的『中央處理器CPU Central Processing Unit,是計算機的心臟,從開機後就『不停的』執行著指令,這些 指令構成了 CPU 懂得的指令集,按照  CPU 硬體設計架構分成了複雜指令集 CISC ,比如 PC 上用的 Intelx86,和精簡指令集 RISC ,就像樹莓派上用的 ARM。這些指令資料構成的程式存放在隨機記憶體 RAM ── 可以想像成『編了地址』,可以用任意地址讀寫的『記憶單元』 ── 上,由 CPU 依序『解譯』執行程式裡的指令,存取程式裡的資料。這種『儲存程式』的計算機模型依循著 Von Neumann 先生的計算機『建築學』architecture 而設計。在這個 CPU 指令解譯器裡,有一個『指令地址指標』── 稱作程式計數器 Program Counter ── 告訴 CPU 『下一個』指令在 RAM 上的哪個地址。每個指令不論是『算術邏輯運算』、『記憶體資料存取』和『控制陳述』 …等等的指令執行時,都會『更新』這個程式計數器。於是 CPU 就能從硬體設計上開機時所固有『起始的』地址上『讀取』fetch 第一個指令,然後開始『執行』execution,再讀取下一個指令再執行,一直的讀取.執行持續不停。由於指令與資料並不區分,都放在相同的記憶體上,就可能發生把資料當作指令或是將指令當成資料的情況,一般會導致『當機』。這個前面說的指令集,就是 CPU 唯一會的『機器語言』── 以二進制方式儲存在記憶體上的一長排位元組。即使最簡單的『組合語言Assembler 功能僅僅提供機器語言的『助憶碼』Assembly Mnemonic ,也得把用它寫的程式『組譯』成機器碼 Machine Code,CPU 才能執行;更不要說這個組合語言自己也得能執行才能進行組譯。假使你覺得組合語言很有意思,你可以看看劍橋大學開的烘焙 Pi 開發作業系統公開課;或是裸裸金屬樹莓派編程打算寫的一本書;以及樹莓派組合碼部落客。這裡藉著簡單介紹『思考著的極客』一文上用 Gnu as 組譯程式寫的 first.s 原始碼欣賞程式組譯這回事︰

/* — first.s */
/* This is a comment */
.global main /* ‘main’ is our entry point and must be global */
.func main /* ‘main’ is a function */

main: /* This is main */
mov r0, #2 /* Put a 2 inside the register r0 */
bx lr /* Return from main */

作者費心的在短短的八行裡試圖說明 as 的語法,此處把他文中詳細的說明節錄簡譯如下︰『/* …… */』是註解,as 會忽略;『 . 』起頭的字是 as 的宣告 directive,『.global main』 告訴 as main 是像 C main 程式一樣的主程式進入點 ── 開始執行的地址 ──;『.func main』 說明 main 是一個函數 function;as 會忽略『空白行』;『main:main 函數標籤 label;這個函數只有兩行指令,『mov r0, #2』,將 2 移入 move 到 ro 暫存器;和『bx lr』分支交換  branch and exchange 跳到 lr 暫存器所指的地址

首先用 as 組譯程式,將 first.s 組譯成 first.o 目的碼 object code ── 尚未『連接』link 成執行檔 ──︰

as -o first.o first.s

然後用 Gnu C 編譯程式 gcc 連接成 first 執行檔

gcc -o first first.o

測試 first ,這裡的『 $? 』是 bash 外殼程式代表程式傳回值的符號,而『 ; 』是接續執行多個寫在一行上的命令︰

./first ; echo $?

想必你早已猜到輸出的結果是『2』。從前述的 first.s 內容來看,應當可以了解組合語言,為什麼叫做低階程式語言 low level 了,因為它偏向機器語言,人們必須清楚了解所用的 CPU 硬體架構,才能好好的掌握它。

雖說第一個高階程式語言是德國Konrad Zuse 先生的 Plankalkül,大約構想於第二次世界大戰末期,然而第一個廣為使用的卻是福傳 Fortran ── Formula Translation 的縮寫。1957 年IBM 當時的工程師約翰·華納·巴克斯 John Warner Backus 因深切體會到編寫程式困難,需要更好的程式語言所創。他也就是知名的『 BNF 』巴科斯-諾爾範式 Backus–Naur Form 的創始者之一,這個範式 是一種表示無上下文脈絡關係 Context Free 文法語言,可以用來描述 CF 這一類的形式語言,這包括了絕大部分的電腦程式語言。其後又有了 1969 年在 Bell Labs circa 由 Ken ThompsonDennis Ritchie 所發展的 B 語言,然後於 1971 年之際演變成 New B,最終於 1972 年變成了今天的 C 語言 ── After B ──,形成了美麗的『ABC』語言傳奇

事實上 Von Neumann 的計算機架構,對於電腦程式語言的發展,有著極為深遠的影響,產生了現在叫做 Von Neumann 程式語言,與Von Neumann 的計算機架構,同形 isomorphism 同構

program variables ↔ computer storage cells
程式變數 對映  計算機的儲存單元

control statements ↔ computer test-and-jump instructions
控制陳述  計算機的『測試.跳至』指令

assignment statements ↔ fetching, storing instructions
賦值陳述  計算機的取得、儲存指令

expressions ↔ memory reference and arithmetic instructions.
表達式  記憶體參照和算術指令

John Warner Backus 曾經斷言,由於電腦圈長期過度強調 Von Neumann 的程式語言與計算機架構,已經產生了『惡性循環』,使得非此類的語言由於不符合經濟而日漸式微,比方 APL 語言 ── 註︰有興趣的,可以參照這裡在 Raspbian 上安裝 ──。

行文至此,不得不提及 Charles H. Moore 先生,他認為像 asgcc 那樣的程式語言,依循著 compile-link-go 編譯.連接.執行的步驟都該叫做『第三代』的電腦語言,因而想發明『第四代 FOURTH』語言,但由於 IBM 1130 電腦作業系統,限制檔案名稱長度最多個字元,以至於 FOURTH 被迫變成了現今稱作『Forth』的電腦程式語言。這是一個以『堆疊 Stack』為中心,用『字典』定義『』方式的一種交互式 interactive 的編譯.解譯寫程式的環境,十分有趣獨特。有時還真不好說它算是低階還是高階語言,彷彿是種『由低到高』的程式編寫世界。你可以參考這份文件的說明,進到 Forth 的國度裡『逍遙遊』!!

 

 

『騛罿』── 非同的禪!!

吉多·范羅蘇姆 Guido van Rossum 先生喜歡看『蒙提·派森的飛行馬戲團』── Monty Python’s Flying Circus,所以把他創始的程式語言叫做 『 Python 』 。Python 巨蟒,《爾雅·釋魚》蟒,王蛇。又《註》蟒,蛇最大者,故曰王蛇。正是『小王子』一書上所說的︰

吞了象,看起來像帽子的那個。

吉多的 Python 『非同』於其他程式語言,居然把『空白』符號寫進了它的『文法』裡,竟然用『對齊的空白』表示程式區塊。如是種種『見地』,匯聚成一條稱作『非同的』pythonic  Way 大道。吉多他的『中心思想』,集中的表現在由 Tim Peters 先生所寫的『 Python 的禪』,收錄在『 this模組 module 裡︰

import this

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
美比醜好

Explicit is better than implicit.
明白比晦暗好

Simple is better than complex.
簡單比複雜好

Complex is better than complicated.
複雜比複雜化好

Flat is better than nested.
平直比疊套好

Sparse is better than dense.
薄落比濃縮好

Readability counts.
可讀性能加分

Special cases aren’t special enough to break the rules.
特例不夠特殊到能夠破壞規矩

Although practicality beats purity.
雖然獨特性能打敗純粹性

Errors should never pass silently.
錯誤不該無言放過

Unless explicitly silenced.
除非指明它是靜默寡詞

In the face of ambiguity, refuse the temptation to guess.
面對含混,拒絕揣測意圖

There should be one– and preferably only one –obvious way to do it.
總有一個,最好是唯一的一個,明白的作法

Although that way may not be obvious at first unless you’re Dutch.
即使起初那條道路並不明顯,除非你很「好辯」

Now is better than never.
當下好於從不

Although never is often better than *right* now.
雖然從不也常常好過馬上

If the implementation is hard to explain, it’s a bad idea.
如果一件事很難說明怎麼做成的,那這個想法不好

If the implementation is easy to explain, it may be a good idea.
反之如果一件事怎麼做,很容易說明白,也許是個好想法

Namespaces are one honking great idea — let’s do more of those!
「名字空間」的理念──響亮著的偉大號角,就讓我們多多用它吧

這麼好的一個程式語言,缺少一個對當的中文譯名,實在可惜。在此野人獻曝,『姑妄言之』。或可譯作『騛罿』ㄈㄟ  ㄊㄨㄥˊ與 Python 音聲相合。『罿』是捕鳥的網、捕魚的網;不管天上飛的,水裡游的,一網打盡。似乎合於 Python 語言多『典範』  的特殊性paradigm ── 『物件導向』、『結構化』和『泛函式』程式設計 ──。『』字,古駿馬名 ──『飛兔』之馬,正可比擬 Python 的『哲學之美』。

讀者就『姑妄聽之』吧!!