看板 Programming 關於我們 聯絡資訊
話說其實從大學起就一直都很想學組合語言,但一直都沒能夠成功的進入組語 的學習領域。 後來陸陸續續接觸了一些其他的程式語言,玩到 Functional Programming 之 後,也漸漸地把學組合語言這件事給拋到腦後了,畢竟光是玩 Functional Programming 就已經玩不玩了說。 只是後來又不小心進到了需要慣 C 的工作領域,重新在 Linux Kerenel 下面 打轉,於是學組語這個念頭又回來了--畢竟,這是可是基礎中的基礎啊,而 且追 Kernel 常常追到最後都是組語。 但問題是組語要怎麼學呢?我想這一定也有很多想學組語,但和我一樣不得其 門而入的朋友有相同的困擾。 以我自己而言,我有莫名其妙、不知道為何會出現的,從 80386 時代遺留下 來的組語書籍(還用 PE2 咧),有自己去書局買的 NASM 的書,也有資工系 開的組合語言課程的課本,甚至是網路上開放下載的教學書籍。 可是以上沒有任何一本書真正讓我進入組語的世界,理由很簡單--這些書我 怎麼看都覺得不對勁,不知道該如何寫出我的第一隻組語程式。 有的一開始就和你講什麼 MOVL 是幹嘛用的,ADD 又是啥,但卻又沒有一隻完 整的程式可以執行試驗--這樣根本就沒感覺啊!根本就不能從錯誤之中學習 啊(例如隨便亂加兩個暫存器會怎樣)! 有的嘛,遵照古老的傳統,一開始就寫一個 Hello World 給你,然後再告訴 你不要管那些 include 的黑魔法,反正程式可以跑就好--等一下,我學組 語就是為了要了解最底層的運作,結果你叫我不要管他? 總而言之,看這些書的挫敗感真的很大,也因為如此,我一直沒有真正下定決 心好好把組合語言給學起來。 一直到前一陣子,我在 Hacking Thursday [1] 的討論區上看到這一本超級棒 的書籍--Programming from the Ground Up [2],這真的是自學組合語言的 好物啊! [1] Hacking Thursday http://hack.ingday.org/ [2] Programming from the Ground Up http://ftp.twaren.net/Unix/NonGNU/pgubook/ 廢話不多說,我們來看書中第一個程式範例: ====================================================================== .section .data .section .text .global _start _start: movl $1, %eax # This is the linux kernel system call for exit movl $0, %ebx # This is the status number return to OS int $0x80 # This wake up the kernel to run exit system call ====================================================================== 三行程式,而且每一行書裡面都解釋的很清楚(是的,包括 System Call 的 部份也有說明,雖然經過簡化與譬喻),沒有任何的黑魔法。 同時,你也可以亂改這個程式,例如試著改變 EBX 暫存器的值,讓他返回不 同的值給 Shell,又或者亂改 EAX 裡面的值,然後讓他產生 Segmentation Falut 而當掉。 真是太神奇有趣了!這才叫學組語嘛。 我真的很佩服作者可以想出把程式的結束狀態代碼當成輸出這個點子,完全避 開了其他書裡面為了要產生輸出而不得不先使用黑魔法的問題。 再舉另一個例子,他的第二隻程式是介紹控制流程和迴圈,要透過他介紹的各 種跳躍指令找到一個數列裡的最大值,這隻程式如下: ====================================================================== .section .data items: .long 3, 6, 7, 10, 22, 34, 12, 0 .section .text .global _start _start: movl $0, %edi # move 0 to index register movl items(,%edi,4), %eax # load the first number movl %eax, %ebx # put it to the EBX (cureent biggest) start_loop: cmpl $0, %eax # check to see if we've hit the end je loop_exit incl %edi # increment index by 1 movl items(,%edi,4), %eax # load next number cmpl %ebx, %eax # compare with current biggest jle start_loop # jump to start_loop if not bigger movl %eax, %ebx # else move this value as the largest jmp start_loop # next turn loop_exit: movl $1, %eax # System Call exit (No. 1) int $0x80 # Singal batman ====================================================================== 同樣的,這隻程式也是利用離開狀態做輸出--所以你用到的,都是你學過的 東西,沒有黑魔法,每一行每一行都可以解釋到底是在做什麼,讓你驗證你是 不是真的了解他。 另外,他用的是 GNU as 的語法,這對我而言有以下幾個好處: - 這是 Linux Kernel 裡面用的東西,我不用再去熟悉其他語法 - 我只要有一台 Linux Box 就可以試著跑書裡的程式 - 這意謂著你可以用 GCC 把 C 語言編譯到組合語言,然後和這本書裡面 的範例做比對,例如講到 Function 的時候,你就可以寫幾個 C 語言 的函數來驗證書裡講的東西。 所以我一定要大推這一本書的啊~~這本書真的是自學組語的必備良方,只要 會一點程式設計,一定可以看得懂的好東西! -- ~ 白馬帶著她一步步地回到中原。白馬已經老了,只能慢慢地走, 'v' Brian Hsu 但終是能回到中原的。江南有楊柳、桃花,有燕子、金魚…… // \\ ( 墳 墓 ) /( )\ 但這個美麗的姑娘就像古高昌國人那樣固執。 【白馬嘯西風】 ^`~'^ http://bone.twbbs.org.tw/blog 『那都是很好很好的,可我偏不喜歡。』 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.32.42.74
aleelyle:= = x86的指令初學者不易學阿 59.105.46.29 02/07 13:33
akasan:先推一個,也立志學組語超久了,結果到現在118.168.190.172 02/07 14:27
akasan:只學會arm跟nds32的...118.168.190.172 02/07 14:27
akasan:x86的就是一直沒找機會補起來XD...118.168.190.172 02/07 14:28
Tankan:你這個不是x86的組語指令? 看起來怪怪的 61.64.195.232 02/07 20:19
brianhsu:是 AT&T 的語法,是 Linux 下比較常用的 114.32.42.74 02/07 21:34
ogamenewbie:推一個, 另外也有ASM版歐 (不過我沒看 218.160.33.60 02/07 21:38