南京大學OS筆記(1)-應用眼中的操作系統


南京大學OS筆記(1)-應用眼中的操作系統

早就想刷一刷南大JYY老師的os課。之前稍微看過幾節,果然講的風趣幽默,而且現場寫代碼展示水平確實很高,這次准備認真刷一刷然后好好記一下筆記。當然lab就不做了,因為已經做過mit的lab了。刷課主要是為了復習基礎知識和學的更深入一點。第一節操作系統歷史就不記筆記了,直接從第二節開始

1. 什么是應用程序

1. (應用)程序

image-20211112143459540

這里學到和csapp里的一致的。下面看一系列代碼演示

image-20211112143348929

當我gcc -c a.c的時候會生成一個a.o。注意-c表示編譯。這里的a.o是可重定位目標文件。而不是可執行目標文件。

image-20211112143543776

而在執行gcc a.o就會把它變成一個可執行目標文件。這里我在我自己的Linux機器上報錯了。

image-20211112143628549

總結一下,程序就是可執行的二進制文件,無論什么程序在Linux系統下都是如此的。

2. ELF二進制文件

image-20211112144054315

正因如此,我們可以用vim直接打開/bin/ls

image-20211112144225135

這是一個二進制文件,所以這里直接顯示亂碼。

xxd可以用來讀二進制文件

image-20211112144930616

這里的Entry point address表示它第一條指令的起始地址。

3. 最簡單的" Hello World"

1. 如果我們有一個下面這樣的代碼

int main () {
	printf("Hello World\n");
}

可以直接運行嗎。看起來沒什么問題,但我們試試

image-20211112150432653

  • 這里會提示我們沒有定義puts,明明是調用了printf為什么會提示puts這是因為printf在底層實際上調用了puts

    這是因為gcc即便在沒有設置優化的情況下。也就是- o0的情況下還是會做優化,把printf簡化成了puts

  • 第二個問題是這里提示了warninng是我們沒有制定代碼的起始位置

2. 如果我們再嘗試一次代碼

int main() {
	
}

這是一個完全空的代碼。但是它還是會報錯

image-20211112151551354

我們需要用gdb調試一下,看看到底為什么出錯了

image-20211112151741453

我們需要單步執行,執行到retrun這里。return指令就是調用main函數的地方。

image-20211112151816072

因此在這里我們觸發了段錯誤。這里我們不能訪問地址為1的地方

3. 正確的嘗試

這里jyy老師引入了一段匯編代碼。讓hello程序變得正確

image-20211112152649823


image-20211112152538586

這里單步執行到了系統調用

%eax 傳遞系統調用號

%rdi 傳遞第一個參數 ,以此類推

2. 應用程序怎么調用操作系統

1.首先看一下syscall的代碼在哪里

image-20211112224001531

objdump指令解釋

Displays information about one or more object files.

這里可以發現我們所有的系統調用都是callq syscall@plt-動態鏈接來自於libc的代碼

2. Main()之前發生了什么?

(面試題)一個普通的C程序第一條指令子啊哪里?

  • ❌ main的第一條指令
  • ❌ libc的_start

image-20211112224757971

可以用gdb調試一下會發現。它的第一條指令會在lib64/ld-linux-x86-64.so這是操作系統自帶的加載器

下面輸入info inferiors看一下有什么問題

  1. 我們發現我們現在運行的這個程序進程號是12305。
  2. 我們使用pmap 12305輸出這個進程的信息。

image-20211112224915863

會發現os已經幫我們做了很多事情所以整個過程是

os自帶的加載器---> 加載libc------> 加載a.out

看下面這個程序。

image-20211112225224690

雖然main是空的。,但是這里的

Hello World
Goodbye, Cruel OS World

還是可以正常輸出

3. Trace的使用

使用strace可以追蹤系統調用

image-20211112225616565

這里跟隨課上jyy老師的腳步分析一下a.out的系統調用

  1. 可以發現第一條系統調用是execve
  2. 然后libc執行了一堆系統調用
  3. 最后才會到我們自己寫的程序

3. 應用眼中的操作系統

image-20211112230110029

可以說所有的程序都是類似的,不斷的調用系統調用。從開始到關閉

1. gcc的系統調用過程

image-20211112230438185

  1. 這里的gcc確實是先利用as來做編譯

  2. 然后用collect2來做鏈接

    image-20211112230829979

    collect2主要用來做合成,會把構造器和析構器的代碼生成出來

image-20211112230917583

  1. 在gcc的最后會調用ld。

image-20211112231510595

2. 其他的應用程序

image-20211112232047854


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM