巔峰造極的程式語言登場,程式設計界的元始天尊!連C語言都恭敬不已!
“哇塞,怎麼可能這麼簡單!”
當C語言老頭兒還是小夥子的時候,第一次見到了彙編,發出了這麼一聲感慨。
在C語言看來,這彙編的指令實在是太簡單了,簡單到了令人髮指的地步,只有這麼幾類指令:
資料傳輸類:
就是把資料從一個位置複製到另外一個位置,比如從記憶體到暫存器,或者從暫存器到記憶體, 或者從暫存器到暫存器。
算術和邏輯運算類:
無非就是加減乘除,AND, OR, 左移,右移
控制類:
比較兩個值,跳轉到某一個位置。
彙編老頭兒非常地驕傲, 他經常囂張地說:“別看我的指令這麼簡單,但是配合我的暫存器和記憶體, 卻能完成你們這些所謂的高階語言的所有功能!”
這暫存器是什麼鬼? C語言腦海中只有記憶體和指標,根本就沒有什麼暫存器的概念, 實際上,這是屬於CPU阿甘的,容量有限,但是速度超級快的儲存部件。
32位CPU暫存器:
陣列
C看著彙編這單薄的小身板,想到自己那優雅的if , 漂亮的while, for ,還有那極為重要的函式呼叫,心裡不由得泛起嘀咕:我的程式怎麼可能被編譯成這麼簡單的彙編?
雖然心裡有點瞧不上,但C小夥還是挺恭敬的:“前輩,在我這裡有個數組的概念,編譯成彙編是什麼樣?”
int num[10];
num[0] = 100;
num[1] = 200;
除了機器語言,那就屬彙編最老,連C語言的第一個編譯器都是用匯編寫的,當之無愧的前輩。
彙編老頭兒沒想到C小夥兒連這個問題都沒弄清楚,說道:“我這裡只認暫存器和記憶體,你這所謂陣列,就是記憶體的一段連續的空間嘛,我只要知道開始地址就可以了。”
C小夥兒一看,好傢伙,連變數名num都不要了。 不過說得也是, 彙編老頭只要記住初始地址,順著地址就能找到所有東西。
“咦,這個什麼0x000083d0不就相當於我的指標麼? ”
“是啊,不過在我這裡,都是地址,忘掉指標吧!”
條件分支
C小夥又想到了自己的if else,在彙編中該怎麼處理?
if(x < y ) { return y - x;} else { return x -y ;}
彙編老頭兒說:“你們這些高階語言啊,就愛搞複雜化,怎麼不用goto呢?”
C小夥說:“goto 被迪傑斯特拉認為是有害的,會破壞結構化,不建議使用!”
“唉,簡單就是美,你們這些高階語言懂不了,我這裡很簡單,就是比較和跳轉指令,從一個地方跳到另外一個地方執行就行了。”
彙編老頭兒一遍感慨,一遍寫道:
我們假設
%eax 暫存器儲存的是y的值,
%edx 暫存器儲存的是x的值。
cmpl%eax,%edx;
比較x和yjge.L1;
如果x>=y,跳轉到.L1處去執行subl%edx,%eax;
計算y-x,結果存到eax暫存器中jmp.done;
跳轉到.done標籤處.L1:subl%eax,%edx;
計算x-ymovl%edx,%eax;把結果存到eax暫存器中.done: ;
計算結束,結果儲存在eax暫存器中
C小夥兒看了半天,終於搞明白了這段彙編程式的含義,這所謂的jge也就是做一個判斷,然後跳轉到特定位置去執行,就像是if 和 goto 的結合。
彙編老頭兒看到C小夥兒懂了, 問道:“你想想你的while 迴圈,for 迴圈,是不是if 和 goto 的包裝而已?”
C小夥兒想了一會:“確實是這樣!”
“這不就結了,我的彙編看起來簡單,但是卻能表達你所有的流程控制語句,不管什麼if else, while, for ,switch ,對吧?”
C小夥兒覺得彙編老頭兒說的都是歪理:“這goto是簡單,可是程式讀起來就非常複雜了啊!”
彙編老頭兒說:“你算是說道了點子上,所謂高階語言,主要是方便人類的編寫和閱讀的,是為了提升人類的效率。
在我這裡,主要是讓CPU阿甘執行的,那傻小子,速度飛快,什麼也不懂,你只要告訴它指令就行,越簡單越好。”
沒想到CPU阿甘聽到了對它的嘲諷,不滿地說:“老夥計,又在背後說我的壞話,我執行了億萬條指令以後,早就悟出了程式的區域性性原理,這你懂不懂?”
函式呼叫
C小夥看到不能難倒彙編老頭兒,想到了自己可以定義函式,精神一振,問道:“函式呼叫你怎麼處理啊?”
int funcA(int a) { ...... funcB(10) ......} int funcB(int b) { ...... funcC(); ......}
看看,這funcA呼叫funcB,funcB又呼叫funcC,函式巢狀呼叫,你那簡單的指令能處理? C小夥兒心裡暗想。
彙編老頭兒不慌不忙:“你可算是問了一個有價值的問題,不過這也難不倒我,我需要記憶體配合一下就行了。”
“看到裡邊的棧幀沒有,每個棧幀都表示一個函式的呼叫!”
“那這棧幀中有什麼東西?” C小夥兒問道。
“細節太複雜,給你畫個示意圖看看吧!”
“不對啊,你這棧幀中有輸入引數,有返回值,可是沒有函式程式碼啊?程式碼去哪兒了?”
“真是幼稚! 這是執行時在記憶體中對函式的表達,那程式碼肯定是在程式碼段啊。” 彙編老頭兒嘲諷道。
程式碼段的指令不斷被CPU阿甘執行,遇到函式呼叫,就建立新的棧幀,函式呼叫結束,棧幀就會銷燬,廢棄。然後返回上一個棧幀。
C小夥兒意識到自己犯了一個大錯誤,他老是想著程式碼的靜態結構,而忽略了執行時的表示。
程式語言的巔峰
他急於挽回面子,趕緊給C++打電話求援:“兄弟,快過來,治一下這個彙編老頭兒!”
C++瞭解了事情的經過,說道:“兄弟,不行啊,別看我有class, 但是最終我也得變成過程化的程式,翻譯成彙編,和你是一樣一樣的。”
“那Python呢, Java 呢?” C小夥兒有點氣急敗壞。
“他們更不行了,是虛擬機器中的語言,他們連彙編老頭兒的面兒都見不著,再說那虛擬機器不就是你自己寫的啊!”
C小夥呆住了,可不是,自己是很多系統級軟體和程式語言的基礎,已經非常貼近硬體了,自己治不了彙編老頭兒,別人肯定也不行啊。
C小夥兒又想到了應用層那複雜的業務邏輯,他們都是由Python,Java, JavaScript等高階語言編寫的;
還用到了什麼OOD,設計模式,函式式,響應式程式設計...... 但是它們都是一層層的抽象,幫助程式設計師更好地編寫程式,在最底層,還是彙編啊。
他嘆了一口氣,對彙編老頭說:“前輩,我服了,您可真是程式語言的巔峰啊。”
“不敢當,還有一個語言比我更厲害!”
“是誰?”
“機器語言! 只有0和1!不信你看看這他們程式設計師的專屬鍵盤。”
最後,不管你是轉行也好,初學也罷,進階也可——【值得關注進入】的程式設計學習進階俱樂部
涉及到:C語言、C++、windows程式設計、網路程式設計、QT介面開發、Linux程式設計、遊戲程式設計、黑客等等......