1. 程式人生 > 其它 >20191315 2.3.1測試

20191315 2.3.1測試

2.3.1測試

1.編輯並執行2.3.1中的程式碼,要求在不修改t2.c 和 t1.c中main函式中的程式碼的情況下,程式執行結果是你的後四位學號。提交程式碼和執行結果截圖。
2.網上學習objdump命令,提交不少於5篇部落格連結和微信讀書上的圖書連結,並給出你認為最好的講解資源的連結或圖書名及章節。
3.用objdump分析第1步中的可執行檔案和目標檔案,提交你的分析截圖以及如何和教材講解內容對應的,比如obj檔案的檔案頭,程式碼段,資料段等,可執行檔案如何連結mysum的。

編輯並執行2.3.1中的程式碼,要求在不修改t2.c和t1.c中main函式中的程式碼的情況下,程式執行結果是你的後四位學號。提交程式碼和執行結果截圖

程式碼

//t1.c
#include <stdio.h>
int mysum(int x, int y);
int g = 1312;
int h;
static int s; 

main(int argc, char *argv[ ])
{
    int a = 1;int b; 
    static int c = 3;
    b = 2;
    c = mysum(a,b) ; 
    printf("sum=%d\n", c) ;  
}
//t2.c
extern int g; 
int mysum(int x, int y) 
{
   return x+y+g;
}

執行結果

網上學習objdump命令,提交不少於5篇部落格連結和微信讀書上的圖書連結,並給出你認為最好的講解資源的連結或圖書名及章節

man

objdump命令

objdump命令是Linux下的反彙編目標檔案或者可執行檔案的命令,它以一種可閱讀的格式讓你更多地瞭解二進位制檔案可能帶有的附加資訊。

常用引數
-f:顯示檔案頭資訊
-d:從objfile中反彙編那些特定指令機器碼的section
-D:反彙編所有section
-h:顯示目標檔案各個section的頭部摘要資訊
-x:顯示所有可用的頭資訊,包括符號表、重定位入口。-x 等價於 -a -f -h -r -t 同時指定
-i:顯示對於 -b 或者 -m 選項可用的架構和目標格式列表
-j name:僅僅顯示指定名稱為name的section的資訊,需與-s一起用
-l:用檔名和行號標註相應的目的碼,僅僅和-d、-D或者-r一起使用使用-ld和使用-d的區別不是很大,在原始碼級除錯的時候有用,要求編譯時使用了-g之類的除錯編譯選項
-r:顯示檔案的重定位入口。如果和-d或者-D一起使用,重定位部分以反彙編後的格式顯示出來
-R:顯示檔案的動態重定位入口,僅僅對於動態目標檔案有意義,比如某些共享庫
-s:顯示指定section的完整內容。預設所有的非空section都會被顯示
-S:儘可能反彙編出原始碼,尤其當編譯的時候指定了-g這種除錯引數時,效果比較明顯。隱含了-d引數。
-t:顯示檔案的符號表入口。類似於nm -s提供的資訊

學習連結

比較好的

用objdump分析第1步中的可執行檔案和目標檔案,提交你的分析截圖以及如何和教材講解內容對應的

  • -f 顯示objfile中每個檔案的整體頭部摘要資訊

  • -h 顯示目標檔案各個section的頭部摘要資訊

  • 顯示.o檔案中的程式碼段資料段的內容

組合語言為具體的機器編寫程式。彙編器是將彙編程式碼轉換為二進位制形式機器程式碼的程式生成的.o檔案稱為目的碼。每個.o檔案都包含

  • 一個檔案頭,包含程式碼段、資料段和 BSS 段的大小。
  • 一個程式碼段,包含機器指令。
  • 一個數據段,包含初始化全域性變數和初始化靜態區域性變數。
  • 一個BSS段,包含未初始化全域性變數和未初始化靜態區域性變數。
  • 程式碼中的指標以及資料和BSS中的偏移量的重定位資訊。
  • 一個符號表,包含非靜態全域性變數、函式名稱及其屬性。
  • -t 顯示檔案的符號表入口。

連結。一個程式可能包含多個.o檔案,這些檔案相互依賴。聯結器將所有.o檔案和必要的庫函式組合成單一的二進位制可執行檔案。連結器執行以下操作:

  • 將.o檔案的所有程式碼段組合成單一程式碼段。對於C語言程式,組合程式碼段從預設的 C啟動程式碼cr0.o開始,該程式碼呼叫main函式。
    顯示檔案的符號表入口>+ 將所有資料段組合成單一資料段。組合的資料段僅包含初始化全域性變數和初始化靜態區域性變數。
  • 將所有BSS段組合成單一bss段。
  • 用.o檔案中的重定位資訊調整組合程式碼段中的指標以及組合資料段、bss段中的偏移量。
  • 用符號表來解析各個.0 檔案之間的交叉引用。比如,當編譯器在t1.c中發現c mysum(a,b)時,它並不知道mysum在何處。所以,它在t1.o中留下一個空白(0)作為mysum的入口地址,但是在符號表的記錄中,必須用mysum的入口地址替換空白。連結器將t1.o與t2.o合併時,它知道mysum在組合程式碼段中的位置。連結器只是用mysum的入口地址替換t1.o中的空白。對於其他交叉引用符號也是如此。由於靜態全域性變數不在符號表中,因此不能提供給連結器。從不同檔案中引用靜態全後變數的任何嘗試都會產生交叉引用錯誤。同樣,如果.o檔案涉及任何未定義的符號或函式名稱,連結器也會產生交叉引用錯誤。如果所有交叉引用都能夠成功分辨,連結器會將產生的組合檔案寫為a.out,這是二進位制可執行檔案。