2019-2020-1 20175223 《信息安全系統設計基礎》第1周學習總結

目錄git


教材學習內容總結

  • 第一週要點:
    • 要點1:vim編輯器的基本操做;
    • 要點2:正則表達式基礎;
    • 要點3:Linux C編程基礎:
      • 編譯器GCC;
      • 調試器GDB;
      • Makefile。
    • 要點4:教材第一章、第七章。

  • 教材第一章 「計算機系統漫遊」 要點:
    • 要點1:信息就是位+上下文;
    • 要點2:存儲設備造成層次結構;
    • 要點3:重要主題(概念):
      • Amdahl 定律;
      • 併發和並行;
      • 抽象。

  • 教材第七章 「連接」 要點:
    • 要點1:靜態連接兩個主要任務:
      • 符號解析;
      • 重定位。
    • 要點2:目標文件:
    • 要點3:符號和符號表;
    • 要點4:符號解析:
      • 連接器如何解析多重定義的全局符號;
      • (未完)


教材學習中的問題和解決過程

1. 生成二進制文件時命令錯誤。

根據PPT中:

的命令出錯。正則表達式

在以下項目結構中:

使用 gcc -c -I/include src/say_hello.c 命令出錯。編程

src/say_hello.c:2:11: 致命錯誤:say_hello.h:沒有那個文件或目錄
    2 | # include "say_hello.h"
      |           ^~~~~~~~~~~~~
編譯中斷。
  • 問題緣由分析:
    gcc命令格式出錯,-I 應與 頭文件所在目錄 分離。vim

  • 問題解決方案:併發

-I頭文件所在目錄 分離,再將生成文件導出到 include 文件夾下,命令以下:編輯器

gcc -c -I include src/say_hello.c -o include/say_hello.o

可生成:函數

[yogile@yogile-pc gcc_test]$ tree
.
├── bin
├── include
│   ├── say_hello.h
│   └── say_hello.o
├── libs
├── makefile
├── Readme.md
└── src
    ├── main.c
    └── say_hello.c

4 directories, 6 files

2. 在最終連接時報錯。

輸入命令 gcc src/main.c -I include/ -L libs/ -o bin/main 報錯。學習

[yogile@yogile-pc gcc_test]$ gcc src/main.c -I include/ -L libs/ -o bin/main
src/main.c: 在函數‘main’中:
src/main.c:5:2: 警告:隱式聲明函數‘say_hello’ [-Wimplicit-function-declaration]
    5 |  say_hello();
      |  ^~~~~~~~~
/usr/bin/ld: /tmp/ccKSn7Vo.o: in function `main':
main.c:(.text+0xa): undefined reference to `say_hello'
collect2: 錯誤:ld 返回 1
  • 問題緣由分析:
    發生"undefined reference to" 錯誤有多種緣由(點擊查看)。在這裏是因爲連接時缺失了二進制文件(say_hello.o)。測試

  • 問題解決方案:

方法一:
將命令中最開始的 "src/main.c" 改成"src/*.c" ,直接將全部的源文件一塊兒從新彙編成二進制文件,再一塊兒編譯。

gcc src/*.c -I include/ -L libs/ -o bin/main

方法二:
直接將缺乏的二進制文件加入編譯命令,在 src/main.c -I 中間添加 include/say_hello.o

[yogile@yogile-pc gcc_test]$ gcc src/*.c -I include/ -L libs/ -o bin/main
[yogile@yogile-pc gcc_test]$ bin/main 
hello word

3. 靜態函數庫、動態函數庫命令編譯步驟。

  • 靜態庫
gcc -c -I include/ src/say_hello.c -o include/say_hello.o

ar rcvs libs/libsay_h.a include/say_hello.o
# 屏幕輸出提示:r - include/say_hello.o

gcc src/*.c -I include/ -L libs/ -o bin/main

# 運行可執行文件便可:
[yogile@yogile-pc gcc_test]$ bin/main
hello word
  • 動態庫
gcc -fPIC -c -I include/ src/say_hello.c -o include_so/say_hello.o

gcc -shared -o include_so/libsay_h.so include_so/say_hello.o

gcc src/main.c include_so/say_hello.o -I include/ -L libs/ -o bin/main_so

# 運行可執行文件便可:
[yogile@yogile-pc gcc_test]$ bin/main_so 
hello word
  • 建立的項目結構
項目結構
[yogile@yogile-pc gcc_test]$ tree
.
├── bin
│   ├── main
│   └── main_so
├── include
│   ├── say_hello.h
│   └── say_hello.o
├── include_so
│   └── say_hello.o
├── libs
│   ├── libsay_h.a
│   └── libsay_h.so
├── makefile
├── Readme.md
└── src
    ├── main.c
    └── say_hello.c

5 directories, 11 files

4. 對連接器解析多重定義全局符號 規則 的疑惑。

強弱符號解析處理規則有三:

  1. 不容許多個同名的強符號;
  2. 如有一個強符號和多個弱符號同名,則則選擇強符號;
  3. 如有多個弱符號同名,則任取一個。

疑惑1:對於規則2,若在 main.c 文件中,定義弱符號 x;在 module_2.c 文件中,定義強符號 x=3,在 main.c 中輸出顯示 x 爲多少?
疑惑2:對於規則3,到底會選用哪一個弱符號?

  • 分析回答:

回答疑惑1:
對於規則2,不管強符號在哪一個模塊定義,在其餘模塊調用同名符號時,連接器都會選擇該模塊的強符號,測試以下。


測試1


main.c

# include <stdio.h>
# include "mod.h"

int x;

int main()
{
    printf("x_start = %d\n", x);
    x=1;
    mod_2();
    printf("x = %d\n", x);
    return 0;
}

module_2.c

# include <stdio.h>
# include "mod.h"

int x=3;

void mod_2()
{
    printf("    x_2 = %d\n", x);
}

編譯運行結果爲:

[yogile@yogile-pc 7.6.1]$ ./mod.out 
x_start = 3
    x_2 = 1
x = 1
# include <stdio.h> # include "mod.h" int x; int main() { printf("x_start = %d\n", x); x=1; mod_2(); printf("x = %d\n", x); return 0; }# include <stdio.h> # include "mod.h" int x=3; void mod_2() { printf(" x_2 = %d\n", x); }[yogile@yogile-pc 7.6.1]$ ./mod.out x_start = 3 x_2 = 1 x = 1

回答疑惑2:
對於規則三,若都是弱符號(即:未初始化,編譯時初值爲0),根據資料,所謂「隨機選定的」是指佔用空間最大的,選定後不會更改,測試以下。


測試2


main.c

# include <stdio.h>
# include "mod.h"

int x;

int main()
{
    printf("x_start = %d\n", x);
    mod_2();
    x=1;
    mod_2();
    printf("x = %d\n", x);
    return 0;
}

module_2.c

# include <stdio.h>
# include "mod.h"

int x;

void mod_2()
{
    printf("    x_2 = %d\n", x);
}

編譯運行結果爲:

[yogile@yogile-pc 7.6.1]$ ./mod.out 
x_start = 0
    x_2 = 0
    x_2 = 1
x = 1
# include <stdio.h> # include "mod.h" int x; int main() { printf("x_start = %d\n", x); mod_2(); x=1; mod_2(); printf("x = %d\n", x); return 0; }# include <stdio.h> # include "mod.h" int x; void mod_2() { printf(" x_2 = %d\n", x); }[yogile@yogile-pc 7.6.1]$ ./mod.out x_start = 0 x_2 = 0 x_2 = 1 x = 1


[代碼託管]

已更改 statistics.sh(ssss.sh)find . -name "*.java" 更改成 find . -name "*.c"
對應倉庫網頁連接:https://gitee.com/Yogile/Cpt_System_Yogile

  • 代碼提交過程截圖:

  • 代碼量截圖:



學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 4000行 20篇 280小時
第一週 66/66 1/1 24/24
  • 計劃學習時間:16小時

  • 實際學習時間:24小時


參考資料

相關文章
相關標籤/搜索