linux環境組合語言程式設計初步——at&t語法
目前正在學習linux彙編,寫寫文章共享一下心得
組合語言作為一種高效的,而且緊密結合硬體平台的程式語言,在作業系統,嵌入式開發等領域都有著十分重要的作用。正因為彙編依賴於硬體結構(cpu指令碼),因此不同體系結構上的組合語言也大相徑庭。目前國內大學的組合語言課程大多以intel平台的語法格式來講述,而市面上講述其他體系結構組合語言的書籍也是寥寥無幾,這就給系統程式設計師研究其他平台彙編**帶來了很大的困難。本文簡單介紹了linux下的at&t語法,以及在linux下彙編的基本方法。
at&t語法起源於at&t貝爾實驗室,是在當時用於實現unix系統的處理器操作碼語法之上而形成的,at&t語法和intel語法主要區別如下:
at&t使用$表示立即數,intel不用,因此表示十進位制2時,at&t為$2,而intel就是2
at&t在暫存器前加%,比如eax暫存器表示為%eax
at&t 處理運算元的順序和intel相反,比如,movl %eax, %ebx是將eax中的值傳遞給ebx,而intel是這樣的mov ebx, eax
at&t在助記符的後面加上乙個單獨字元表示操作中資料的長度,比如movl $foo, %eax等同於intel的mov eax, word ptr foo
長跳轉和呼叫的格式不同,at&t為ljmp $section, $offset,而intel為jmp section:offset
主要的區別就是這些,其他的細節還有很多,下面給出乙個具體的例子來說明
code:
#cpuid.s sample program
.section .data
output:
.ascii "the processor vendor id is '************'/n"
.section .text
.globl _start
_start:
movl $0, %eax
cpuid
movl $output, %edi
movl %ebx, 28(%edi)
movl %edx, 32(%edi)
movl %ecx, 36(%edi)
movl $4, %eax
movl $1, %ebx
movl $output, %ecx
movl $42, %edx
int $0x80
movl $1, %eax
movl $0, %ebx
int $0x80
這個程式的作用是查詢cpu的廠商id,其中:
,ascii定義字串(和intel格式完全不同).section是宣告段的語句,.data和.text是段名,分別為資料段和**段,_start是gas(gnu彙編器)的預設入口標籤,表示程式從這裡開始執行。.globl將_start宣告成了外部程式訪問的標籤。cpuid為指令請求cpu的指定資訊,該指令用eax作為輸入,ebx,edx,ecx作為輸出,這裡將0作為cpuid的輸入指令,請求返回cpu的廠商id字串。返回的結果,乙個12位元組的字串,分別儲存在三個暫存器中,其中ebx存放低4位,edx中間4位,ecx高4位(注意順序!)。接下來定義乙個指標edi,edi指向output的開始位址,然後接著的3條語句將output裡的x替換為廠商資訊。28(%edi)中的28表示偏移量,即整個位址為%edi裡的位址加上28個位元組,這個位址正好是output裡第乙個x的位址。再接下來就是列印結果了,這裡用到了linux的乙個系統呼叫(int 0x80),該系統呼叫的引數分別為:eax 系統呼叫號,ebx 要寫入的檔案描述符,ecx 字串首位址,edx 字串長度,程式裡這些個引數的值分別為4,1(標準輸出),output的位址和42。最後再次呼叫1號系統呼叫-退出函式,返回shell,這次ebx中的值是返回給shell的退出**,0表示無異常
然後彙編連線執行程式:
code:
$as -o cpuid.o cpuid.s
$ld -o cpuid cpuid.o
$./cpuid
the processor vendor id is 'genuineintel'
$
本人的電腦是pentium m的cpu所以返回的結果是genuineintel。
幾點說明:
1)linux的標準彙編環境為as,ld,gdb,gprof,objdump等gnu開發除錯工具,除了gdb外,其他全部隨binutils包發布。其中as使用的是at&t語法。在linux下也可以使用na**來進行intel格式的匯程式設計序編寫,具體na**的使用方法見本人blog的《na**使用手冊》
2)linux下彙編的系統呼叫為int 0x80,和dos下的int 21h大同小異,只不過傳遞引數不同
3)段宣告語句.section不需要像intel格式那樣在段結尾的時候加上段結束標誌(segment/ends),下乙個段的開始自動標誌著上個段的結束
4)簡單程式的入口標籤不是必須要定義的,ld會自己判斷入口,但是會給出警告
5)本文部分內容**於richard blum的《professional assembly language》一書
組合語言程式設計
1.彙編語句的三種基本型別 2.標號相關 3.變數相關 4.運算元定址方式 buffer dw 500 x 17 rept 500 這是乙個重複巨集,以下重複彙編500遍 x x 979 mod 65535 這句話我也不懂 dw x endm 巨集在這裡結束transto10 proc near 函...
組合語言程式設計
乙個完整的源程式通常由若干邏輯段組成,包括資料段 附加段 堆疊段和 段。它們分別對映到儲存器中的物理段上。每個邏輯段以segment語句開始,以ends結束,整個源程式用end語句結尾。段中存放源程式的所有指令碼 資料 變數等則放在資料段和附加段中。程式中可以定義堆疊段,也可以直接利用系統中的堆疊段...
組合語言 學習筆記2 彙編程式設計環境
3.段暫存器 4.指令指標暫存器 二 實位址下的儲存器定址方式 三 堆疊儲存技術 四 程式彙編連線與除錯方法 在微機原理與接 術課程中,我學的是16位的彙編,現在總結一下32位的彙編。不過這兩者是一脈相承的,因此會有很多相同的地方。算術邏輯運算後的結果特徵 16位 附加段暫存器es fs和gs 存放...