在OS X下想從0開始學習彙編語言,需要什麼軟體和書籍?

計算機系學生想自學彙編語言,苦於網上找不到對應的軟體推薦和入門教程,求老司機帶飛


確實是件蛋疼的事。

放個傳送門給題主好了:Assembly language programming under OS X with NASM

x86-64的彙編自己找本書學學就好。手上有這本書但還沒讀,看別人的評價似乎還不錯:《x86/x64體系探索及編程》

最好還是邊讀彙編的入門介紹書,邊找個C編譯器(例如Clang)實驗各種代碼生成出來的彙編是怎樣的,能建立起高級-&>底層的映射的話,上手速度會快很多。


自己走過些彎路,當初是自己寫一段代碼,然後看生成的彙編,對比著學,不懂得就看intel的說明書。後來看csapp(Computer Systems: A Programmer"s Perspective (2nd Edition): Randal E. Bryant, David R. O"Hallaron: 9780136108047: Amazon.com: Books)發現人家第三章專門是講如何看編譯器生成的彙編的,而且是給0基礎的人講的,由淺入深非常適合新手。常用的指令都有涉及,而且還配有相應C的代碼。題主可以抽點時間專門看看第三章入個門,之後想深入的話,就按照上面幾個猛人的推薦的資料吧:)


不要在mac上寫彙編 這是自討苦吃!!

裝一個32-bit的 linux虛擬機 開始的時候編譯器用gcc 因為他生成的彙編相對ms的編譯器更加規整 相對乾淨

開始從c語言生成彙編看看 熟悉熟悉calling convention 對stack的操作 之後幹什麼就取決於你的學習目的了


試試 julia 語言吧,表達能力強,然後每條語句,每個函數都可以看到彙編代碼。

例子是在 Windows 7 64bit 系統下跑的,其他系統會略有不同,但本質相似。都能夠讓你理解你所寫的各種代碼在底層是如何運行的。嗯,在 Ubuntu 64bit 下是一模一樣的。


下載intel c++ compiler,直接用內嵌彙編練習,等到你熟練之後才轉MASM從應用程序的啟動開始寫,支持到所有最新指令。


以前走了很多彎路,現在寫下來給後來者參考吧.

很多人介紹彙編,都是寫一段彙編,裡面從一個類似main方法的入手,比如@RednaxelaFX 大神給的那個連接.還有一個叫&<&&>的書也是.這些無非是借著彙編的語言形式,寫著我們原本就很熟悉的c語言程序.事實上,我認為這除了對彙編語言本身熟悉了之外,沒有多大實質性的進步.比如,你還是不知道,為什麼把一個"Hello world"的二進位序列(偽指令得到的)的地址放到一個寄存器,然後設置些其他寄存器參數,然後終端里就顯示了個什麼hello world的東西.

過程如下(參考mac上nasm彙編helloworld):

SECTION .data

msg: db "Hello World!", 0x0a
len: equ $-msg

SECTION .text
global _main

kernel:
syscall
ret

_main:
mov rax,0x2000004
mov rdi,1
mov rsi,msg
mov rdx,len
call kernel

mov rax,0x2000001
mov rdi,0
call kernel

然後運行如下

對,這很簡單,也是彙編,但是這意義其實不是很大.這和我們用printf實現由多大區別?事實上,我們學彙編的很大程度的目的是想擺脫黑盒子,也就是任何第三方函數的都不要,我要自己實現各printf怎麼辦,事實上,這很難辦到,畢竟我們運行在操作系統上,許可權上已經封死了.所以我們需要直接在一個無操作系統的系統上,看看我們一個指令一個指令的運行效果,一步步是怎麼操作硬體的,我想這才是大多數真正執著於學習彙編的目的吧,與其說是學彙編,倒不如說是對計算機的興趣導致想深挖計算機的原理.本著這種原則,王爽老師那本&<&<彙編語言&>&>其實是不合適的.儘管裡面介紹了很多debug,看寄存器值,內存值等等,在dos下搞得風生水起,然而依舊依賴一個環境.而且在真正寫自己代碼前還有弄些各種東西.

所以我推薦一本叫&<&&>這本書籍

所以我推薦一本叫&<&&>這本書籍

所以我推薦一本叫&<&&>這本書籍

理由上面說了,書上推薦使用的是nasm,簡單介紹下裡面的部分內容:

我就想寫下自己的指令,不要一開始就定義什麼代碼段,數據段,人家還沒入門好嘛

好的,那我們開始

;;文件名test.asm
db 0x11,0xFF
mov ax,0x11

對,第一行定義了0x11,0xFF沒錯,就是兩個數字,沒什麼作用,第二個是把0x11這個16進位數放到ax寄存器里(沒錯現在是16位指令集下的)

執行nasm test.asm就得到了test這個二進位文件,用16進位打開,如下

沒錯,就是這麼簡單,11是第一行的0x11,FF是第一行的0xFF,剩下的B81100就是mov ax,0x11了,可以想像B8代表了一種從立即數到寄存器0x11=&>ax的傳送指令,而11就是那個0x11,ax就是00表示

接下來是一段及其簡單的hello world

mov ax,0xb800 ;指向文本模式的顯示緩衝區
mov es,ax

;以下顯示字元串"Hello world"
mov byte [es:0x00],"H"
mov byte [es:0x01],0x07
mov byte [es:0x02],"e"
mov byte [es:0x03],0x07
mov byte [es:0x04],"L"
mov byte [es:0x05],0x07
mov byte [es:0x06],"l"
mov byte [es:0x07],0x07
mov byte [es:0x08],"l"
mov byte [es:0x09],0x07
mov byte [es:0x0a],"o"
mov byte [es:0x0b],0x07
mov byte [es:0x0c]," "
mov byte [es:0x0d],0x07
mov byte [es:0x0e],"W"
mov byte [es:0x0f],0x07
mov byte [es:0x10],"o"
mov byte [es:0x11],0x07
mov byte [es:0x12],"r"
mov byte [es:0x13],0x07
mov byte [es:0x14],"l"
mov byte [es:0x15],0x07
mov byte [es:0x16],"d"
mov byte [es:0x17],0x07
mov byte [es:0x18],"!"
mov byte [es:0x19],0x07

infi: jmp near infi ;無限循環
times 510-($-$$) db 0
db 0x55,0xaa

對,你沒看錯,就是硬把Hello World對應的字元放到0xb800裡面,然後硬填充很多0,然後某個位置以0x55,0xaa結尾.這個代碼的運行不需要任何環境,當然,有環境卻因為已經由操作系統進入保護麽時候反而不能運行.所以我們用虛擬機來運行,當然把這段代碼放到u盤裡,用真機運行也是ok的.

虛擬硬碟選用的是vhd,然後用virtualbox和qemu都可以運行.

效果如下:

因為我們只把我們要顯示的區域附上了值,其餘的位置則原來是什麼就是什麼,qemu的內置bios沒有給我們清空,而virtual box的bios默認清空了,則顯示如下

對,這個hello world不需要任何操作系統!!!甚至每個有效位置的比特都是我們能預計的,即使還可以通過內存段,批量複製的方式,不過我認為這個方式是對初學者最友好的!!

好了,入門書籍推薦: x86彙編語言 (豆瓣) 這裡是僅僅推薦為0基礎入門書籍,了解從16位到32位的轉變過程,想要了解更多,這個世界就複雜了畢竟我連32位都沒理解透,64位根本可以說不懂

工具的話,visual studio code,弄個nasm的插件即可,安裝上virtual box和qemu nasm就可以開始弄,當然如果熟悉vim或者emacs的話,自己配合插件或者自己寫插件實現更高效的效果當然是最好的.上面的empty.vhd是用virtual box創建的固定大小的vhd文件,該文件分為兩個部分,前面的內容是模擬的硬碟的數據,後面是vhd的標識數據,所以我們彙編好的test只需要merge到empty.vhd的前面部分,merge命令可以用c語言很快實現:(思路如下)

讀一個File 作為輸入(編譯好的文件)
讀一個File 作為模板(空vhd文件)
一個File 作為輸入文件(生成的具有自定義代碼的vhd文件)
循環每個buffer,把輸入的數據讀到後寫入輸入文件,然後順便讀完相同長度的模板部分,
讀完編譯好的文件後,把剩下的模板部分全部寫到輸出文件中,這樣就得到前面是有效代碼,大
小和模板文件一樣的有效的vhd文件


我學彙編,主要就是靠課堂上老師講的東西。

課本基本上被我當Dictionary查指令和中斷用了。

可是當時學的是16位的Windows下的彙編,局限性太大。

後來看《Orange"s 一個操作系統的....》,照著上面講的寫引導代碼,發現可以用好多新指令,於是上網查。。。先寫了個MBR引導代碼,然後開始寫分區的引導代碼,最終很費力的寫出來了一個FAT32下的,只佔用一個扇區的,完全無法Debug,完全無法重構的,載入根目錄下「OSLoader」文件的引導代碼。(至今沒調通。。。。。T_T)


軟體: dosbox + masm


王爽寫的彙編語言


學彙編還是買一塊單片機開發板來吧。這樣更有感覺。


都從0開始了,這問題也跟os x也沒一毛錢關係了。


推薦閱讀:

從用戶體驗的角度來講,為什麼 OS X 不能合併文件夾?
如何評價 iPhone 和 OS X Yosemite 的計算器交互設計存在的問題?
MacBook Pro 與 MacBook Air 各有何優劣?
一直使用 Windows 的人如何儘快熟練使用 OS X?
為什麼都說 MacBook Pro 和 OS X 下比較適合寫代碼?

TAG:macOS | 學習 | 彙編語言 |