一、Linux彙編——初識彙編

前序

    原本想Qt能繼續堅持下來,但是繞了一大圈,最終仍是選擇回到學期伊始的Linux彙編編程上來。鑑於圖書館只能借到這本書,雖然不厚,可是內容仍是比較實用豐富,做爲入門教程至關不錯。之後將不斷更新其閱讀內容、我的感悟和相關彙編代碼。一方面和你們分享,另外一方面,也鍛鍊我寫博文的能力和培養記錄的良好習慣。爲之後工做作鋪墊。至於Qt,我想先推推——C++11正在看,因此仍是但願有一個比較好的鋪墊。基礎夯實了,後面的路感受會好走一些。
shell

正文

第二章 內存詳解

    這裏的內存就先不詳細說了,能夠參考其餘資料。
編程

    主要說下環境:該書使用32位X86彙編,因此默認一個字=4Bytes數組

尋址方式

    一、當即數尋址:指令中包含傳輸的數字,如 :movl  $1, %eax,表示將數「1」存儲到寄存器eax中。oop

    二、寄存器尋址:指令中給出要訪問的寄存器號,如:movl $1, %eax,尋找的爲eax寄存器spa

    三、直接尋址: 指令中直接給出內存的段內偏移地址。如 movl $1, 2 表示將數「1」存入內存ds:2中code

    四、變址尋址:基址用常數表示,偏移量存儲在寄存器中。同時能夠固定某個整數做爲比例因子(步進)。(數組的遍歷)教程

    五、間接尋址:寄存器中存儲要訪問的內存偏移量。索引

    六、基址尋址:寄存器存儲基址,一個常數表示偏移量。(訪問結構性數據)   ip

第三章 編寫第一個程序

程序1;

#目的:退出程序,向Linux內核返回一個狀態碼
#輸入:無
#輸出:想Linux內核返回狀態碼,程序運行結束後,用shell命令:echo $? 查看返回的狀態碼
#變量:%eax 系統調用號
        %ebx 返回狀態嗎
.section .data 
.section .text
.globl _start
_start: movl $1, %eax #系統調用號
        movl $0, %ebx #返回操做碼
        int 0x80        #中斷調用

如上爲彙編程序exit.s,編譯程序:    as exit.s -o exit.o內存

連接程序 :   ld exit.o -o exit

運行程序:./exit

查看返回碼:echo $?

知識點:

一、.section .data :「.」表示彙編程序的僞指令,指導編譯器的行爲。該段爲數據段。

二、.section .text:該段爲代碼段,本段存放須要執行的命令。

三、.globl _start:表示標號_start後面的代碼段爲全局,其表示爲程序的入口。

四、前綴「e」表示32位寄存器,前綴「r」表示64位寄存器,如「rax」

五、通用寄存器有如下幾個:%eax, %ebx, %ecx ,%edx, %edi, %esi

        專用寄存器有如下幾個:%ebp,%esp,%eip,%eflags

六、當進行系統調用時,%eax存系統調用號,%ebx存向系統返回的狀態碼,int表示中斷,此指令將調用終端程序。

程序2:

#目的:尋找一維數組中最大值
#變量:    %edi——當前數組元素的下表(索引)
#          %ebx——當前最大值
#          %eax——當前數據項
#數據段:data_items:0表示數組結束
.section .data
    data_items: .long 3,67,32,222,45,75,54,33,22,11,66

.section .text
.globl _start
_start: movl $0, %edi                     #索引值從0開始
        movl data_items(,%edi,4), %eax    #使用變址尋址法,給出步進長度爲4
        movl %eax, %ebx                   #初始時第一項爲最大值
   
start_loop: cmpl $0, %eax    #判斷是否到達數組末尾
            je loop_exit     #到達數組末尾,退出循環,做收尾工做
        incl %edi            #未到達末尾,索引加1
        movl data_items(,%edi,4), %eax
        
        cmpl %ebx, %eax    #與當前最大值進行比較
        jle start_loop     # %eax <= %ebx
        
        movl %eax, %ebx    # %eax > %ebx,則進行交換
        jmp start_loop
loop_exit:
        movl $1, %eax      # 1爲系統調用exit()的調用號
        int $0x80          #中斷調用

編譯:as maximum.s -o maximum.o

連接:ld maximum.o -o maximum

運行:./maximum

查看返回結果:echo $?

知識點

一、data_items中的「.long」表示數據類型,彙編語言中有如下數據類型可供使用:

(1).byte:佔1 byte, 範圍0~255

(2).int  :佔2 byte,範圍:0~65535

(3).long :佔4 byte, 範圍:0~4 294 967 295

(4).ascii:用於將字符輸入內存,每一個字符佔一個byte,如:.ascii "hello world\0",「\0」表示字符串末尾

二、對於數組,能夠有以下方式表示:

(1)數組長度做爲第一個元素

(2)數組末尾用特殊符號標記

三、注意上面的最大值不能超過255,由於程序的退出狀態碼最大爲255。

四、條件跳轉指令:當使用條件跳轉指令時,須要使用cmpl指令對兩個數進行比較:cmpl a , b。條件跳轉指令有:

(1)je :當 a==b時,跳轉到目標地址

(2)jg:當 b>a時,則跳轉。

(3)jge:當 b >= a時,則跳轉

(4)jl : 當 b <a 時,則跳轉

(5)jle :當 b<=a時,則跳轉

(6)jmp:無條件跳轉

五、尋址方式:

(1)索引尋址方式:地址或偏移(%基址寄存器,%索引寄存器,比例因子),

結果地址=地址或偏移+%基址或偏移量寄存器+比例因子 * %索引寄存器

須要注意:地址或偏移量、比例因子必須爲常數,其他兩個必須爲寄存器,若省略任何一項可用0代替。地址和偏移量寄存器可省略,但需加後面的「逗號」。

(2)其餘尋址方式參考第二章內容

六、關於指令中數據的字長:

(1)movl表示傳輸一個「字」的數據,若只想傳輸一個「字節」,則使用指令movb,

(2)%eax的低字節爲%ax,%ax的高一字節爲%ah,低一字節爲%al。

相關文章
相關標籤/搜索