Linux下的匯編語言之系統(tǒng)調(diào)用
作為最基本的編程語言之一,匯編語言雖然應(yīng)用的范圍不算很廣,但重要性卻勿庸置疑,因為它能夠完成許多其它語言所無法完成的功能。就拿 Linux 內(nèi)核來講,雖然絕大部分代碼是用 C 語言編寫的,但仍然不可避免地在某些關(guān)鍵地方使用了匯編代碼,其中主要是在 Linux 的啟動部分。由于這部分代碼與硬件的關(guān)系非常密切,即使是 C 語言也會有些力不從心,而匯編語言則能夠很好揚(yáng)長避短,***限度地發(fā)揮硬件的性能。
第三課時:Linux 系統(tǒng)調(diào)用
即便是最簡單的匯編程序,也難免要用到諸如輸入、輸出以及退出等操作,而要進(jìn)行這些操作則需要調(diào)用操作系統(tǒng)所提供的服務(wù),也就是系統(tǒng)調(diào)用。除非你的程序只完成加減乘除等數(shù)學(xué)運(yùn)算,否則將很難避免使用系統(tǒng)調(diào)用,事實上除了系統(tǒng)調(diào)用不同之外,各種操作系統(tǒng)的匯編編程往往都是很類似的。
在 Linux 平臺下有兩種方式來使用系統(tǒng)調(diào)用:利用封裝后的 C 庫(libc)或者通過匯編直接調(diào)用。其中通過匯編語言來直接調(diào)用系統(tǒng)調(diào)用,是***效地使用 Linux 內(nèi)核服務(wù)的方法,因為最終生成的程序不需要與任何庫進(jìn)行鏈接,而是直接和內(nèi)核通信。
和 DOS 一樣,Linux 下的系統(tǒng)調(diào)用也是通過中斷(int 0x80)來實現(xiàn)的。在執(zhí)行 int 80 指令時,寄存器 eax 中存放的是系統(tǒng)調(diào)用的功能號,而傳給系統(tǒng)調(diào)用的參數(shù)則必須按順序放到寄存器 ebx,ecx,edx,esi,edi 中,當(dāng)系統(tǒng)調(diào)用完成之后,返回值可以在寄存器 eax 中獲得。
所有的系統(tǒng)調(diào)用功能號都可以在文件 /usr/include/bits/syscall.h 中找到,為了便于使用,它們是用 SYS_
ssize_t write(int fd, const void *buf, size_t count);
該函數(shù)的功能最終是通過 SYS_write 這一系統(tǒng)調(diào)用來實現(xiàn)的。根據(jù)上面的約定,參數(shù) fb、buf 和 count 分別存在寄存器 ebx、ecx 和 edx 中,而系統(tǒng)調(diào)用號 SYS_write 則放在寄存器 eax 中,當(dāng) int 0x80 指令執(zhí)行完畢后,返回值可以從寄存器 eax 中獲得。
或許你已經(jīng)發(fā)現(xiàn),在進(jìn)行系統(tǒng)調(diào)用時至多只有 5 個寄存器能夠用來保存參數(shù),難道所有系統(tǒng)調(diào)用的參數(shù)個數(shù)都不超過 5 嗎?當(dāng)然不是,例如 mmap 函數(shù)就有 6 個參數(shù),這些參數(shù)***都需要傳遞給系統(tǒng)調(diào)用 SYS_mmap:
void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);
當(dāng)一個系統(tǒng)調(diào)用所需的參數(shù)個數(shù)大于 5 時,執(zhí)行int 0x80 指令時仍需將系統(tǒng)調(diào)用功能號保存在寄存器 eax 中,所不同的只是全部參數(shù)應(yīng)該依次放在一塊連續(xù)的內(nèi)存區(qū)域里,同時在寄存器 ebx 中保存指向該內(nèi)存區(qū)域的指針。系統(tǒng)調(diào)用完成之后,返回值仍將保存在寄存器 eax 中。
由于只是需要一塊連續(xù)的內(nèi)存區(qū)域來保存系統(tǒng)調(diào)用的參數(shù),因此完全可以像普通的函數(shù)調(diào)用一樣使用棧(stack)來傳遞系統(tǒng)調(diào)用所需的參數(shù)。但要注意一點,Linux 采用的是 C 語言的調(diào)用模式,這就意味著所有參數(shù)必須以相反的順序進(jìn)棧,即***一個參數(shù)先入棧,而***個參數(shù)則***入棧。如果采用棧來傳遞系統(tǒng)調(diào)用所需的參數(shù),在執(zhí)行int 0x80 指令時還應(yīng)該將棧指針的當(dāng)前值復(fù)制到寄存器 ebx中。
【編輯推薦】
- 2.3 用匯編語言編寫程序
- 術(shù)語匯編 基本CSS濾鏡概述
- 琢石成器—Windows環(huán)境下32位匯編語言程序設(shè)計
- 3.1.3 as86匯編語言程序的編譯和鏈接
- 3.1.2 as86匯編語言程序
- 3.1.1 as86匯編語言語法
- 3.2.6 as匯編命令