隨著Linux的普及,如何在Linux平台下進行編程,尤其是匯編成為大家關注的一個問題,但是這方面資料卻很少。在遍訪網站和論壇後,我把收集到的資料結合本人總結的一些經驗跟大家分享一下。 Nasm介紹 Linux下的匯編編譯器有多種,語法也不盡相同,其中GAS是比較基本的匯編工具。但是GAS采用的不是我們通常在DOS體系下使用的匯編語法,它采用的是AT&T的語法格式,這是繼承Unix的特點,與Intel語法格式有很大的不同。 作為一個從DOS轉型到Linux的匯編愛好者,AT&T的格式不太容易接受,學習起來也非常困難。我要介紹的是另一種匯編工具Nasm,這跟DOS下用的Intel x86匯編風格的Masm類似,是Linux中語法與DOS最為相像的一種匯編工具。 下面就以hello.asm這個小程序為例,介紹如何用Nasm在Linux下進行匯編。 hello.asm hello world for Linux section .text extern puts global main main: push dWord msge ; call puts ; add esp, byte 4 ; ret ; msge: db “Hello World!”,0 Nasm編譯命令如下: Nasm -f elf hello.asm gcc -o hello hello.o “Nasm -f elf hello.asm”是將把hello.asm匯編成elf object文件。“gcc -o hello hello.o”會把hello.asm匯編成二進制可執行文件hello.com 。 Nasm -f命令的參數主要有aout和elf兩種,如果不能確定Linux系統應該用aout還是elf,可以在Nasm目錄中輸入命令file Nasm,如果輸出“Nasm: ELF 32-bit LSB executable i386(386 and up) Version 1”應該使用elf;如果輸出“Nasm: Linux/i386 demand-paged executable(QMAGIC) ”應該使用aout。用命令Nasm -h可以取得Nasm命令行的完整說明。 程序說明 hello.asm是調用了Linux系統的puts函數,原理與調用DOS下C語言的函數相同,先用extern聲明puts是外部函數,再把參數(即msg的地址)壓入堆棧,最後call函數實現輸出。 再來看一個程序: section .text global main main: mov eax,4 ; 4號調用 mov ebx,1 ; ebx送1表示輸出 mov ecx,msge ; 字符串的首地址送入ecx mov edx,14 ; 字符串的長度送入edx int 80h ; 輸出字串 mov eax,1 ; 1號調用 int 80h ; 結束 msge: db “Hello World!”,0ah,0dh 這個程序與DOS程序十分相似,而且結果同hello.asm一樣,它用的是Linux中的80h中斷,相當於DOS下的21h中斷,只是因為Linux是32位操作系統,所以采用了eax、ebx等寄存器。 Nasm與Masm的區別 1.大小寫問題 與Linux系統一樣,Nasm是區分大小寫的,Hello與hello將是不同的標識符。而在DOS或OS/2下使用Masm進行匯編,需要加入UPPERCASE參數才能區分大小寫。 2.對[ ]的使用 Nasm對[ ]的使用與Masm也有所不同,Nasm規定所有的表達式和內存操作數都必須寫在[ ]中。下面舉兩個例子來說明。 Masm的語法: mov ax,bar mov ax,es:[di] mov ax,[di]+1 Nasm的語法: mov ax,[bar] mov ax,[es:di] mov ax,[di+1] 3.關於變量類型 Nasm中不存儲變量類型,Masm中即使是通過[ ]尋址方式的變量也必須要指定變量類型。Nasm中不支持LODS, MOVS、STOS、SCAS、CMPS、INS、OUTS等類型,只支持lodsb、lodsw等已經指定類型的操作,並且Nasm中不再有assume操作,段地址完全取決於存入段寄存器的值。 關於Nasm詳細的使用方法及語法還可以參閱Nasm使用手冊。 小結 Linux作為一個多用戶的操作系統,與DOS有著非常大的區別的,特別涉及到操作系統原理時,與DOS可以說是截然不同。Linux操作系統實際是從抽象資源操作到具體硬件操作之間的接口。 對Linux這樣的多用戶操作系統來說,它需要避免用戶對硬件的直接訪問,並防止用戶之間的互相干擾,所以Linux接管了BIOS調用和端口輸入輸出,如果要通過Linux對硬件進行訪問就需要用到SystemCall。它實際上是許多C函數的集合,可以在匯編程序中被調用,調用方法與DOS下的匯編完全相同,並且用Nasm匯編時不用鏈接額外的庫函數。
來源:賽迪網