[心得] 自學組合語言的必備良方! - 看板Programming

文章推薦指數: 80 %
投票人數:10人

以我自己而言,我有莫名其妙、不知道為何會出現的,從80386 時代遺留下來的組語書籍(還用PE2 咧),有自己去書局買的NASM 的書,也有資工系開的組合 ... 批踢踢實業坊 › 看板Programming 關於我們 聯絡資訊 返回看板 作者brianhsu(墳墓)看板Programming標題[心得]自學組合語言的必備良方!時間SunFeb711:27:442010 話說其實從大學起就一直都很想學組合語言,但一直都沒能夠成功的進入組語 的學習領域。

後來陸陸續續接觸了一些其他的程式語言,玩到FunctionalProgramming之 後,也漸漸地把學組合語言這件事給拋到腦後了,畢竟光是玩Functional Programming就已經玩不玩了說。

只是後來又不小心進到了需要慣C的工作領域,重新在LinuxKerenel下面 打轉,於是學組語這個念頭又回來了--畢竟,這是可是基礎中的基礎啊,而 且追Kernel常常追到最後都是組語。

但問題是組語要怎麼學呢?我想這一定也有很多想學組語,但和我一樣不得其 門而入的朋友有相同的困擾。

以我自己而言,我有莫名其妙、不知道為何會出現的,從80386時代遺留下 來的組語書籍(還用PE2咧),有自己去書局買的NASM的書,也有資工系 開的組合語言課程的課本,甚至是網路上開放下載的教學書籍。

可是以上沒有任何一本書真正讓我進入組語的世界,理由很簡單--這些書我 怎麼看都覺得不對勁,不知道該如何寫出我的第一隻組語程式。

有的一開始就和你講什麼MOVL是幹嘛用的,ADD又是啥,但卻又沒有一隻完 整的程式可以執行試驗--這樣根本就沒感覺啊!根本就不能從錯誤之中學習 啊(例如隨便亂加兩個暫存器會怎樣)! 有的嘛,遵照古老的傳統,一開始就寫一個HelloWorld給你,然後再告訴 你不要管那些include的黑魔法,反正程式可以跑就好--等一下,我學組 語就是為了要了解最底層的運作,結果你叫我不要管他? 總而言之,看這些書的挫敗感真的很大,也因為如此,我一直沒有真正下定決 心好好把組合語言給學起來。

一直到前一陣子,我在HackingThursday[1]的討論區上看到這一本超級棒 的書籍--ProgrammingfromtheGroundUp[2],這真的是自學組合語言的 好物啊! [1]HackingThursday http://hack.ingday.org/ [2]ProgrammingfromtheGroundUp http://ftp.twaren.net/Unix/NonGNU/pgubook/ 廢話不多說,我們來看書中第一個程式範例: ====================================================================== .section.data .section.text .global_start _start: movl$1,%eax#Thisisthelinuxkernelsystemcallforexit movl$0,%ebx#ThisisthestatusnumberreturntoOS int$0x80#Thiswakeupthekerneltorunexitsystemcall ====================================================================== 三行程式,而且每一行書裡面都解釋的很清楚(是的,包括SystemCall的 部份也有說明,雖然經過簡化與譬喻),沒有任何的黑魔法。

同時,你也可以亂改這個程式,例如試著改變EBX暫存器的值,讓他返回不 同的值給Shell,又或者亂改EAX裡面的值,然後讓他產生Segmentation Falut而當掉。

真是太神奇有趣了!這才叫學組語嘛。

我真的很佩服作者可以想出把程式的結束狀態代碼當成輸出這個點子,完全避 開了其他書裡面為了要產生輸出而不得不先使用黑魔法的問題。

再舉另一個例子,他的第二隻程式是介紹控制流程和迴圈,要透過他介紹的各 種跳躍指令找到一個數列裡的最大值,這隻程式如下: ====================================================================== .section.data items: .long3,6,7,10,22,34,12,0 .section.text .global_start _start: movl$0,%edi#move0toindexregister movlitems(,%edi,4),%eax#loadthefirstnumber movl%eax,%ebx#putittotheEBX(cureentbiggest) start_loop: cmpl$0,%eax#checktoseeifwe'vehittheend jeloop_exit incl%edi#incrementindexby1 movlitems(,%edi,4),%eax#loadnextnumber cmpl%ebx,%eax#comparewithcurrentbiggest jlestart_loop#jumptostart_loopifnotbigger movl%eax,%ebx#elsemovethisvalueasthelargest jmpstart_loop#nextturn loop_exit: movl$1,%eax#SystemCallexit(No.1) int$0x80#Singalbatman ====================================================================== 同樣的,這隻程式也是利用離開狀態做輸出--所以你用到的,都是你學過的 東西,沒有黑魔法,每一行每一行都可以解釋到底是在做什麼,讓你驗證你是 不是真的了解他。

另外,他用的是GNUas的語法,這對我而言有以下幾個好處: -這是LinuxKernel裡面用的東西,我不用再去熟悉其他語法 -我只要有一台LinuxBox就可以試著跑書裡的程式 -這意謂著你可以用GCC把C語言編譯到組合語言,然後和這本書裡面 的範例做比對,例如講到Function的時候,你就可以寫幾個C語言 的函數來驗證書裡講的東西。

所以我一定要大推這一本書的啊~~這本書真的是自學組語的必備良方,只要 會一點程式設計,一定可以看得懂的好東西! -- ~白馬帶著她一步步地回到中原。

白馬已經老了,只能慢慢地走, 'v'BrianHsu但終是能回到中原的。

江南有楊柳、桃花,有燕子、金魚…… //\\(墳墓) /()\但這個美麗的姑娘就像古高昌國人那樣固執。

【白馬嘯西風】 ^`~'^ http://bone.twbbs.org.tw/blog『那都是很好很好的,可我偏不喜歡。

』 -- ※發信站:批踢踢實業坊(ptt.cc) ◆From:114.32.42.74 →aleelyle:==x86的指令初學者不易學阿59.105.46.2902/0713:33 推akasan:先推一個,也立志學組語超久了,結果到現在118.168.190.17202/0714:27 →akasan:只學會arm跟nds32的...118.168.190.17202/0714:27 →akasan:x86的就是一直沒找機會補起來XD...118.168.190.17202/0714:28 推Tankan:你這個不是x86的組語指令?看起來怪怪的61.64.195.23202/0720:19 →brianhsu:是AT&T的語法,是Linux下比較常用的114.32.42.7402/0721:34 推ogamenewbie:推一個,另外也有ASM版歐(不過我沒看218.160.33.6002/0721:38



請為這篇文章評分?