Linux下的組譯工具設計

來源:互聯網
上載者:User
Linux彙編簡介:

一、組合語言的優缺點:

由於Linux是用C寫的,所以C自然而然的就成為了Linux的標準程式設計語言。大部分人都把彙編給忽略了,甚至在網際網路上找資料都是非常的困難,很多問題都需要靠自己來嘗試。我認為這樣對待組合語言是不公平的,不能只看到它的缺點,當然也不能只看到它的優點,下面把它的優缺點作一個比較:

優點:組合語言可以表達非常底層的東西

.可以直接存取寄存器和I/O
.編寫的代碼可以非常精確的被執行
.可以編寫出比一般編譯系統高效的代碼
.可以作為不同語言或不同標準的介面

缺點:組合語言是一個非常低級的語言

.非常冗長單調,在DOS下編程時就可以體會到

.易出BUG,且調試困難
.代碼不易維護
.相容性不好,與硬體關係非常緊密

總的來說,組合語言要用在必須的地方,盡量少用彙編編寫大型程式,多採用inline模式。

二、組合語言工具:

DOS下常用的工具MASM和TASM到Linux下就用不起來了,Linux有自己的彙編工具,而且種類非常的多。其中
gas可以算是標準配置,每一種Linux中都包括有gas,但是GAS採用的不是我們通常在DOS下採用的彙編文法 ,它採用的是AT&T的文法格式,與intel文法格式有很大的不同。

如果要採用與DOS接近的文法格式,就必須用另一種彙編工具NASM,NASM基本與MASM相同,但也有不少地方有較大區別,特別涉及到作業系統原理時,與DOS可以說是截然不同。

Linux組譯工具設計:

一、Hello,world!

幾乎所有的語言入門篇都是以“Hello,world!”為例,那麼我也以Hello,world!為例開始。

;-------------NASM’s standalone Hello-World.asm for Linux --------

section .text
extern puts
global main

main:
   push
dword msg ;stash the location of msg on the stack.
   call puts ;call the
"puts" routine (libc?)
   add esp, byte 4 ;clean the stack?
   ret
;exit.

msg:
  db "Hello World!",0

編譯:
nasm –f elf
hello.asm
gcc –o hello hello.o

說明:這個程式實際上是調用了,Linux系統的puts函數,原理與調用DOS下C語言的函數相同,先用extern聲明puts是外部函數,再把參數(即msg的地址)壓入堆棧,最後call函數實現輸出。

我們再來看一個程式:

section .text
global main

main:
  mov
eax,4 ;4號調用
  mov ebx,1 ;ebx送1表示stdout
  mov ecx,msg ;字串的首地址送入ecx

  mov edx,14 ;字串的長度送入edx
  int 80h ;輸出字串
  mov eax,1 ;1號調用

  int 80h ;結束
msg:
  db "Hello World!",0ah,0dh
(編譯同上一個程式)

這個程式與DOS程式十分相似,它用的是linux中的80h中斷,相當於DOS下的21h中斷,只是因為Linux是32位作業系統,所以採用了EAX、EBX等寄存器。但是Linux作為一個多使用者的作業系統與DOS又是有著非常大的區別的。要寫出有特色的程式,不瞭解作業系統和硬體是不行的。下面我介紹一下Linux作業系統。

二、Linux作業系統簡介:

作業系統實際是抽象資源操作到具體硬體操作細節之間的介面。對Linux這樣的多使用者作業系統來說,它需要避免使用者對硬體的直接存取,並防止使用者之間的互相干擾。所以Linux接管了BIOS調用和連接埠輸入輸出,
關於連接埠輸入輸出方面請參閱Linux IO-Port-Programming HOWTO。而要通過Linux對硬體硬體進行訪問就需要用到System
Call,實際上是許多C的函數,可以在組譯工具中調用,調用方法與DOS下的彙編完全相同 ,而且用ASM彙編時不用連結額外的庫函數。

Linux與DOS的主要區別在於記憶體管理、進程(DOS下無進程概念)、檔案系統,其中記憶體管理和進程與彙編 編程的關係比較密切:

1、記憶體管理:

對任一台電腦而言,其記憶體以及其他資源都是有限的。為了讓有限的實體記憶體滿足應用程式對記憶體的大
需求量,Linux採用了稱為“虛擬記憶體”的記憶體管理方式。Linux將記憶體劃分為容易處理的“記憶體頁”,在
系統運行過程中,應用程式對記憶體的需求大於實體記憶體時,Linux可將暫時不用的記憶體頁交換到硬碟上,這
樣,閒置記憶體頁可以滿足應用程式的記憶體需求,而應用程式卻不會注意到記憶體交換的發生。

2、進程

進程實際是某特定應用程式的一個運行實體。在Linux系統中,能夠同時運行多個進程,Linux通過在短的
時間間隔內輪流程執行這些進程而實現“多任務”。這一短的時間間隔稱為“時間片”,讓進程輪流程執行的
方法稱為“調度”,完成調度的程式稱為發送器。通過多任務機制,每個迸程可認為只有自己獨佔計算
機,從而簡化程式的編寫,每個進程有自己單獨的地址空間,並且只能由這一進程訪問,這樣,作業系統 避免了進程之間的互相干擾以及“壞”程式對系統可能造成的危害。

為了完成某特定任務,有時需要綜合兩個程式的功能,例如一個程式輸出文本,而另一個程式對文本進行
排序。為此,作業系統還提供進程間的通訊機制來協助完成這樣的任務。Linux中常見的進程間通訊機制有 訊號、管道、共用記憶體、訊號量和通訊端等。

三、Linux下的彙編工具:

Linux下的彙編工具可謂百家爭鳴,不像DOS下都要給MASM和TASM給控制了。但是Linux下每一種彙編工具都
有很大的區別,要想全部掌握幾乎是不可能的,下面我介紹幾種常用的彙編工具,重點介紹NASM及其使用 和文法。

1、GCC

GCC其實是GNU的C語言產品,但它支援Inline Assemble,在GCC中inline
assemble使用就像宏一樣,但它比宏能更清楚更準確的表達機器的工作狀態。

C是彙編編程的一個高度概括,它可以減少許多彙編中的麻煩,特別是在GCC這個C編譯器中,assemble似乎 起不了多大的作用。

2、GAS

GAS是Linux各版本中基本的彙編工具,但它採用的是AT&T的文法標準與Intel的文法標準有很大的不同,對
於DOS編程的我們來說,學習起來是非常困難的。當然如果要精通Linux下的彙編編程,學習GAS也是非常必 要的,具體的文法標準可以參看Using GNU
Assembler。

3、GASP

GASP是GAS的擴充,它增強了GAS對宏的支援。

4、NASM

NASM是linux中文法與DOS最為相像的一種彙編工具。雖說如此,它與MASM也是有著很大區別的。

.NASM的使用格式如下:

nasm –f -o

例如:

nasm -f elf
hello.asm

將把hello.asm彙編成ELF object檔案,而

nasm -f bin hello.asm -o
hello.com

會把hello.asm彙編成二進位可執行檔hello.com

nasm –h

將會列出NASM命令列的完整說明。

NASM不會有任何輸出,除非有錯誤發生。

-f
在Linux下主要有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與MASM的主要不同:

首先與linux系統一樣,nasm是區分大小寫,Hello與hello將是不同的標識符,如果要彙編到DOS或OS/2
,需要加入UPPERCASE參數。

其次,nasm中記憶體運算元都是以[ ]表示。

在MASM中

foo equ
1
bar dw 2
mov ax,foo
mov ax,bar

將被彙編成完全不同的指令,雖然它們在MASM中的表達方式完全一樣。而NASM完全避免了這種混亂,它使用的是這樣的規則:所有對記憶體的操作都必須通過[ ]來實現。例如上例中對bar的操作就要寫成如下形式
mov
ax,[bar]。由此可見,nasm中對offset的使用也是沒有必要的(nasm中無offset)。nasm對[ ]的使用 與masm也有所不同,所有的運算式都必須寫在[
]中,下面舉兩個例子來說明:

masm                             nasm
mov
ax,table[di]                 mov ax,[table+di]
mov
ax,es:[di]                   mov ax,[es:di]
mov
ax,[di]+1                    mov ax,[di+1]

nasm 中不儲存變數類型,原因很簡單masm中通過[
]定址方式的變數也必須要指定類型。nasm中不支援 LODS, MOVS, STOS, SCAS, CMPS, INS,
OUTS,只支援lodsb、lodsw等已經指定類型的操作。nasm中不再有 assume操作,段地址完全取決於存入段寄存器的值。

關於NASM的使用方法及文法還可以參閱NASM使用手冊。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.