文章總列表

[書評] Programming from the Ground Up

Programming from the Ground Up
http://ftp.twaren.net/Unix/NonGNU/pgubook/

(免費下載)


----


這是一本觀點獨特的書, 他用組合語言的方式, 闡述程式最底層的世界
這樣講聽來有點空洞, 直接看這本書第一個程式吧


Chapter 3. Your First Programs


----


.section .text

.global _start

_start:

movl $1, %eax
movl $0, %ebx
int $0x80


這是 Linux底下, 一段小到不能再小的程式
程式從 _start 進入, 然後設定 x86 暫存器: %eax = 1, %ebx = 0
int $80 是發出軟體中斷的指令, 其中 0x80 代表 Linux System Call

呼叫 System Call 的時候
%eax 放 system call ID, 1 表示離開程式
%ebx 表示 main function 的 return value

呼叫完這個 system call, Linux 就會結束程式
並把 %ebx 的內容當作 main() 的回傳值

User 接下來可以在 shell 裡, 打 echo $? 觀察這個回傳值


----


這個例子真的口味獨特 !!

他解釋一般程式是怎麼和 OS 溝通, 怎麼呼叫 system call
另外用很少的程式碼, 解釋組合語言的設施
看過這一小段程式, 起碼我知道, 當我呼叫 exit() 時, 原來做了這些事

書上還有用組合語言, 寫一小段程式, 開檔, 把所有字轉大寫, 存檔, 關檔
WHAT !! 用組合語言做這些事喔 !!
當我親自寫了這段程式, 心中的感動是無以言喻的 :)

推薦給所有想知道事物真正面貌的人閱讀 :)


----


Chapter 4 "All About Functions"

函數, 對應到的 assembly 語言, 這個是極端重要的 topic
靠這章的幫忙, 我總算是懂 x86的 stack frame
而且也真的寫了一些 assembly function 來呼叫

這章的範例是一個函數, 計算 2^3 + 2^5, 然後回傳

書上的玩法是從頭到尾都用 assembly, 我是先寫 C 版本, 搭配一個 main() 呼叫

int power(int base, int exp)
{
int ret = 1;
for(i=0; i< exp; i++)
ret *= base;
return ret;
}

下一步, 把 power() 改成用 assembly 寫, 混用 assembly 和 C
最後, 再把整個 C 都換成 assembly, 這樣玩下來收穫良多


----


Chapter 5 Dealing with Files

看到這章的標題, 我還真的懷疑看錯了... 檔案處理耶 !!
一般的檔案處理依賴神秘的 fopen/fwrite/fread, 或是底層的 open/read/write
書上告訴你, 這些東西都是藉由 OS 的 system call 完成

在呼叫 system call 之前, 把對應的 call ID 和參數放在暫存器裡
然後執行 INT 0x80, OS就會接手剩下的任務了
這章節真的很不錯, 隱藏在 open/read/write 底下的細節, 全部都出來了
而且用組合語言, 自己寫 open/read/write, 成就感滿點 !!

實現的手段和 chapter.4 一樣, 先用 C 刻出骨架, 再逐漸換成組合語言
我不知道這樣做對不對, 對 C我的掌握度高, 而且有骨架比較容易驗證 assembly
全系統直接從 assembly 開始寫, 我想我受不了 XD


----


Chapter 6 "Reading and Writing Simple Record"

這章揭露怎麼處理 struct (C 語言), 搭配 chapter 5 的檔案處理
我覺得受到的刺激沒有上一章那麼強悍
而且看到組語的數目直線上升, 我有點受不了了 XD


----


Chapter 7 "Developing Robust Programs"

這章有點像講軟體工程, 他告訴你程式設計師拙於估算 schedule XD
書上給了幾個建議, 基本上是 "testing-driven" 程式設計方式
有種開發方式建議在撰寫程式碼之前, 先寫好 test case
Test case 日後可以反覆驗證程式, IC的 test bench 就是類似的觀點


----


Chapter 8 "Sharing Functions with Code Libraries"

站在巨人的肩膀上, 所以我們在 Standard C Library 的基礎上寫程式
不然連 printf() 都得自己寫, 實在是太難過了

這章用深入淺出的方式, 介紹怎麼連結函式庫, 對應的 Linker 指令怎麼下
這一小段指令值得寫在這裡...

as helloworld.s -o helloworld.o
ld -dynamic-linker /lib/ld-linux.so.2 helloworld.o -lc -o helloworld

-dynamic-linker /lib/ld-linux.so.2 指示 Linker 去哪裡找 dynamic linker
-lc 表示連結 LIBC (Library C), 實際會連結到 /lib/libc.so.6
helloworld.o 表示連結的目標 (我們寫的程式)
-o helloworld 代表 linker 的輸出是 helloworld

書上最後一個範例, 作者介紹怎麼產生 shared library
我最近才剛在 debug 時, 感受過這些機制的威力, 看這章特別有感覺
Shared library 機制用範例講, 真的是無比清楚


----


Chapter 9 "Intermediate Memory Topics"

"The Memory Layout of a Linux Program"
搭配 Jserv 的 "深入淺出Hello World, 這裡看得到完整的記憶體配置

搭配 memory layout, 作者揭示了動態配置記憶體和 OS 之間的關聯
原來配置記憶體, 也是搭配 system call, 用 C++ 的 new/delete
最好知道底層"可能"的實作細節, 比較好

作者很有意思, 竟然用 assembly 寫了一套 new / delete 的程式庫 (雖然效能很差)
我很喜歡這個範例, 比如他透過實作, 告訴你 new 要記憶體時, 其實多要了一些
他在前面偷偷塞了一些資料, 從記憶體區塊中間把指標回傳
所以說, 小筆資料儘量不要用動態配置, 根本的原因在這裡 (overhead大)

這一章整體碰觸的 topic 很複雜, 但是作者拿捏的洽到好處, 值得一看


----


Chapter 10 "Counting Like a Computer"

2's complement
Binary <-> decimal
AND/OR/XOR logical operation
Bit-Wise operation
Big/Little Endian

像我這種每天被 fixed point 運算折磨的人, 這章是選擇直接跳過
畢竟我可是每天用身體感受啊


----


Chapter 11 "High-Level Language"
Chapter 12 "Optimization"
Chapter 13 "Moving On from Here"

這三章都比較短, 比較沒有我喜歡的底層的東西, 我當故事書很快的讀過


----


Appendix A. GUI Programming

用 gtk 在 Linux 上寫視窗程式... 而且是用 assembly... 算了...


----


Appendix B. Common x86 Instructions

這是一個不錯的 reference, 他還簡單的介紹 assembler 的虛指令 (directive)
基本上這些資料真的要找, google一大堆


----


Appendix C. Important System Calls

Linux 一些書上出現過的 system call 列表


----


Appendix D. ASCII Codes


----


Appendix E. C Idioms in Assembly Language

值得一看, 可以大概認識平常用的 C, 會怎麼對應到組語 (for x86)


----


Appendix F. Using GDB Debugger

托這本書的福? 我總算會用 GDB debug 了
用命令下中斷, 單步執行, 印 call stack 實在很有意思 (也很不直覺)
我覺得 GDB 值得學, 看完這本書, 我又多一個 debug 的武器了

留言

Zack寫道…
偶然想花點時間看看這本書,然後找到您的文章。
您寫得真是不錯,看來我應該要把他看完。

這個網誌中的熱門文章

幼犬書桌椅選擇心得 升降桌 兒童桌椅

Herman Miller Aeron 一代氣壓棒維修

JUJU-250 升降桌 電腦主機 桌下安裝 調整心得