AT&T彙編學習總結一-彙編語言前言準備

  • 通用寄存器:當處理器處理數據時,通用寄存器用於臨時存放數據。

    1. EAX:用於操作數和結果數據的累加器
    2. EBX:指向數據內存段中的數據的指針
    3. ECX:字符串和循環操作的計數器
    4. EDX:I/O指針
    5. EDI:用於字符串操作的目標的數據指針
    6. ESI:用於字符串操作的源的數據指針
    7. ESP:堆棧指針
    8. EBP:堆棧數據指針
  • 段寄存器:專門用於引用內存位置

    平坦內存模式:把全部系統內存表示爲連續的地址空間

    分段內存模式:把系統內存劃分爲獨立段的組。

    實地址模式

    1. CS:代碼段
    2. DS:數據段
    3. SS:堆棧段
    4. ES:附加段指針
    5. FS:附加段指針
    6. GS:附加段指針
  • 指令指針寄存器:EIP寄存器、又稱“程序計數器”,指令指針指向要執行的下一條指令。

  • 控制寄存器:五個控制寄存器用於確定處理器的操作模式、與當前正在執行的任務特性。不能直接訪問控制寄存器中的值,但可以把控制寄存器包含的數據傳送給通用寄存器。

    1. CR0控制操作模式和處理器狀態的系統標誌
    2. CR1當前沒有使用
    3. CR2內存頁面錯誤信息
    4. CR3內存頁面目錄信息
    5. CR4支持處理器特性和說明處理器特性能力的標誌。
  • 標誌:用來確定程序功能是否成功執行的唯一途徑。

  • 狀態標誌:用來表明處理器進行的數學操作的結果。

    標誌 位 名稱志
    CF 0 進位標誌
    PF 2 奇偶校驗標誌
    AF 4 輔助進位標誌
    ZF 6 零標誌
    SF 7 符號標誌
    OF 11 溢出標誌

  • 控制標誌:用於控制處理器的特定行爲,控制標誌——DF標誌、即方向標誌,用於控制處理器處理字符串的方式。
  • 當DF標誌被設置1時,字符串指令自動遞減內存地址以便到達字符串的下一個字節; 當DF=0時,。。。遞增。。。
  • 系統標誌:用於控制操作系統級別的操作

    標誌 位 名稱
    TF 8 陷阱標誌
    IF 9 中斷使能標誌
    IOPL 12和13 I/O特權級別標誌
    NT 14 嵌套任務標誌
    RF 16 恢復標誌
    VM 17 虛擬8086模式標誌
    AC 18 對準檢查標誌
    VIF 19 虛擬終端標誌
    VIP 20 虛擬中斷掛起標誌
    ID 21 識別標誌

    x87浮點單元(簡稱FPU)

    FPU寄存器 描述
    數據寄存器 用於浮點數數據的8個80位寄存器
    狀態寄存器 報告FPU狀態的16位寄存器
    控制寄存器 控制FPU精度的16位寄存器
    標誌寄存器 描述8個數據寄存器的內容的16位寄存器
    FIP寄存器 指向下一條FPU指令的48位FPU指令指針
    FDP寄存器 指向內存中的數據的48位FPU數據指針
    操作碼寄存器 保存FPU處理的最後指令的11位寄存器
    多媒體擴展(簡稱MMX)

    單指令多數據(SIMD):SIMD模型使用擴展的寄存器長度和新的數字格式來加快實施多媒體表現所需的複雜數字處理

    流化SIMD擴展(SSE)

    二. 相關的工具

    彙編器:把彙編語言源代碼轉化爲處理器的指令碼

    彙編語言源代碼程序有三部分:

    操作碼助記符

    數據段

    命令

    彙編器之間最大的區別是彙編命令

    MASM

    NASM

    gas(一個獨特特性是能夠創建不同於程序設計所在平臺的平臺的指令碼,缺陷是不能在宿主系統上測試生成的程序)

    HLA(高級彙編器)

    連接器:鏈接目標代碼的過程設計到解析程序代碼中聲明的所有定義好的函數和內存地址標籤

    調試器大多數調試器提供的基本功能:

    在一個受控制的環境下運行程序,指定任何必須的運行時參數。

    在程序內的任何位置停止程序。

    檢查數據元素,比如內存位置和寄存器

    在程序運行時改變程序中的元素以便幫助消除缺陷。

    編譯器的工作是把高級語言轉化爲處理器能夠執行的指令碼。

    目標代碼反彙編器

    簡檔器:能夠跟蹤每個函數在執行過程中被使用時花費了多長處理器時間。

    GNU彙編器(gas),具有爲以下幾種不同硬件平臺彙編指令碼的能力:

    VAX

    AMD 29K

    Hitachi H8/300

    Intel 80960

    M680x0

    SPARC

    Intel 80x86

    Z8000

    MIPS

    安裝彙編器(在binutils包內)

    包 描述
    add2line 把地址轉換爲文件名和行號
    ar 創建、修改和展開文件存檔
    as 把彙編語言代碼彙編爲目標代碼
    c++filt 還原C++符號的過濾器
    gprof 顯示程序簡檔信息的程序
    ld 把目標代碼文件轉換爲可執行文件的連接器
    nlmconv 把目標代碼轉換爲Netware Loadable Module格式
    objcopy 複製和翻譯目標文件
    ranlib 生成存檔文件內容的索引
    readelf 按照ELF格式顯示來自目標文件的信息
    size 列出目標文件或者存檔文件的段長度
    strings 顯示目標文件中的可打印字符串
    strp 丟棄符號
    windres 編譯Microsoft Windows資源文件
    nm 列出目標文件的符號
    objdump 顯示來自目標文件的信息
    安裝binutils包

    rpm: rpm -qa | grep binutils

    deb: dpkg -l | grep binutils

    使用匯編器gas,命令行可執行程序:as

    as命令行參數:

    參數 描述
    -a 指定輸出中包含哪些清單
    -D 包含它用於向下兼容,但是被忽略
    –defsym 在彙編源代碼之前定義符號和值
    -f 快速彙編,跳過註釋和空白
    –gstabs 包含每行源代碼的調試信息
    –gstabs+ 包含專門的gdb調試信息
    -I 指定搜索包含文件的目錄
    -J 不警告帶符號溢出
    -K 包含它用於向下兼容,但是被忽略
    -L 在符號表中保存本地符號
    –listing-lhs-width 設置輸出數據列的最大寬度
    –listing-lhs-width2 設置連續行的輸出數據列的最大寬度
    –listing-rhs-width 設置輸出源代碼的最大寬度
    –listing-cont-lines 設置輸出的單一行在清單中輸出的最大行數
    -o 指定輸出目標文件的名稱
    -R 把數據段合併進文本段
    –statistics 顯示彙編使用的最大空間和總時間
    -v 顯示as的版本號
    -W 不顯示警告信息
    – 對於原文件使用標準輸入
    操作碼語法:Intel和AT&T語法區別

    AT&T使用$表示立即操作數,而Intel的立即操作數是不需要界定的。

    AT&T在寄存器名稱前加上前綴%,而Intel無。在AT&T語法引用EAX寄存器寫爲%eax

    AT&T語法處理源和目標操作數時使用相反的順序。把十進制4傳送給EAX寄存器,AT&T語法:mov1 $4, %eax ,而Intel語法是mov eax, 4

    AT&T在助記符後面使用一個單獨的字符來引用操作數中使用的數據長度,而Intel語法中數據長度被聲明爲單獨的操作數。AT&T的指令mov1 $test, %eax 等同於Intel語法的mov eax, dword ptr test

    長調用和跳轉使用不同語法定義段和偏移值。AT&T語法使用jmp section, offset,而Intel語法使用jmp section:offset

    GNU連接器ld用於把目標代碼文件連接爲可執行文件或者庫文件。

    GNU編譯器,GNU編譯器集合爲gcc,參數詳解

    參數 描述
    -c 編譯或者彙編代碼,但是不進行連接
    -S 編譯後停止,但是不進行彙編
    -E 預處理後停止,但是不進行編譯
    -o 指定要使用的輸出文件
    -v 顯示每個編譯階段使用的命令
    -std 指定使用的語言標準
    -g 生成調試信息
    -pg 生成gprof製作簡檔要使用的額外代碼
    -O 優化可執行代碼
    -W 設置編譯器警告信息級別
    -pedantic 按照C標準發佈強制性診斷清單
    -I 指定包含文件的目錄
    -L 指定庫文件的目錄
    -D 預定義源代碼中的宏
    -U 取消任何定義了的宏
    -f 指定用於控制編譯器行爲的選項
    -m 指定與硬件相關的選項
    GNU調試器程序

    gcc使用參數

    參數 描述
    -b 設置遠程調試時串行接口的線路速度
    -batch 以批處理模式運行
    -c 指定要分析的核心轉儲文件
    -cd 指定工作目錄
    -d 指定搜索源文件的目錄
    -e 指定要執行的目錄
    -f 調試時以標準格式輸出文件名和行號
    -nx 不執行.gdbinit文件的命令
    -q 安靜模式——不輸出介紹
    -s 指定符號的文件名
    -se 指定符號和要執行的文件名
    -tty 設置標準輸入和輸出設備
    -x 從指定的文件執行gdb命令
    在gdb命令提示下,調試命令:

    命令 描述
    break 在源代碼中設置斷點以便停止執行
    watch 設置監視點,當變量到達特定值時停止執行
    info 觀察系統元素,比如寄存器、堆棧、內存
    x 檢查內存位置
    print 顯示變量值
    run 在調試器內開始程序的執行
    list 列出指定的函數或者行
    next 執行程序中的下一條指令
    step 執行程序中的下一條指令
    cont 從停止的位置繼續執行程序
    until 運行程序,直到到達指定的源代碼行

    GNU objdump程序:可以查看顯示彙編語言代碼,而且能夠顯示生成的原始指令碼。-d把目標代碼反彙編爲指令碼

    GNU簡檔器程序(gprof):用於分析程序的執行和確定應用程序中的“熱點”在什麼位置。“熱點”是程序運行時需要最多處理時間的函數。一般爲數學密集型的函數,但I/O密集型的函數也會增加處理時間。

    輸出格式參數

    -p 不輸出所有函數的一般簡檔,或者不顯示指定函數的

    -g

    分析參數

    雜項參數

    三. 彙編語言程序範例

  • 程序的組成
    組成:
    數據段:是在可執行程序內聲明指令碼的地方,數據段聲明帶有初值的數據元素
    bss段:bss段聲明使用零或者null值初始化的數據元素
    文本段
    定義段:GNU彙編器使用.section命令語句聲明段。.section語句只使用一個參數——它聲明段的類型。
    bss段總是應該安排在文本段之前,數據段可以移到文本段之後,但不標準。因需易閱讀,將所有數據定義集中在源代碼的開頭。

            定義起始點:當彙編語言被轉換爲可執行文件時,連接器必須知道指令碼的起始點是什麼。對於使用分散在源代碼各個位置的若干函數的更加複雜的程序。
    
            GNU彙編器聲明一個默認標籤或稱標識符,用作應用程序的入口點。
    
            _start標籤用作表明程序應從這條指令開始。若連接器找不到此標籤,它會產生錯誤標籤。
    
            若連接器找不到_start標籤,它會試圖查找程序的起始點,但對於複雜的程序,不能保證連接器能正確地作出猜測。
    
            可以使用_start之外的其他標籤作爲起始點。使用連接器的-e參數定義新的起始點的名稱。
    
            除在應用程序中聲明起始標籤之外,還需要爲外部應用程序提供入口點。這裏使用.globl命令完成。
    
            .globl命令聲明外部程序可以訪問的程序標籤。如果編寫被外部彙編語言或者C語言程序使用的一組工具,就應該使用.globl命令聲明每個函數段標籤。
    
    
    
                 創建簡單程序
    
                 CPUID指令是一條彙編指令,不容易從高級語言應用程序執行它。它是請求處理器的特定信息並且把信息返回到特定寄存器中的低級指令。
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章