成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

程序人生-Hello’sP2P-創(chuàng)新互聯(lián)

第1章 概述 1.1 Hello簡介

P2P:From Program to Process,即程序從一個項目變成一個進程的過程。

做網(wǎng)站、成都網(wǎng)站設(shè)計,成都做網(wǎng)站公司-創(chuàng)新互聯(lián)已向數(shù)千家企業(yè)提供了,網(wǎng)站設(shè)計,網(wǎng)站制作,網(wǎng)絡(luò)營銷等服務(wù)!設(shè)計與技術(shù)結(jié)合,多年網(wǎng)站推廣經(jīng)驗,合理的價格為您打造企業(yè)品質(zhì)網(wǎng)站。

程序員通過鍵盤輸入可得hello.c(program)c語言源程序,hello.c在預(yù)處理器(cpp)處理后得到hello.i,通過編譯器(ccl),得到匯編程序hello.s,再通過匯編器(as),得到可重定位的目標(biāo)程序hello.o,最后通過鏈接器(ld)得到可執(zhí)行的目標(biāo)程序hello(process)。

020:From Zero-0 to Zero-0,即程序從零開始又以零結(jié)束的過程。

在執(zhí)行程序的過程中,操作系統(tǒng)為hello分配了虛擬內(nèi)存,shell為hello創(chuàng)建了一個新的子進程,并在這個進程中調(diào)用execve函數(shù),加載器將hello從磁盤中加載到內(nèi)存,并將PC值設(shè)置為程序的入口,進入 main 函數(shù)執(zhí)行目標(biāo)代碼。當(dāng)程序運行結(jié)束后, shell 父進程負責(zé)回收 hello 進程,內(nèi)核刪除相關(guān)數(shù)據(jù)結(jié)構(gòu)。

1.2 環(huán)境與工具 1.2.1硬件環(huán)境 X64 CPU;2GHz;2G RAM;256GHD Disk 以上 1.2.2 軟件環(huán)境 ????? Visual Studio 2010 64位以上;CodeBlocks 64位;vi/vim/gedit+gcc 1.2.3 開發(fā)工具 ????????????? Windows7/10 64位以上;VirtualBox/Vmware 11以上;Ubuntu 16.04 LTS 64????????? 位/優(yōu)麒麟 64位 以上; 1.3 中間結(jié)果

hello.c-程序員編寫的c語言源程序

hello.i-預(yù)處理后的源程序

hello.s-編譯后的匯編程序

hello.o-匯編后的可重定位的目標(biāo)文件

hello-鏈接后的可執(zhí)行文件

elf.txt- hello.o的elf格式文件

helloelf.txt- hello的elf格式文件

1.4 本章小結(jié)

本節(jié)對hello的P2P和020過程進行了大致介紹,并給出了整個過程中所使用的環(huán)境和工具及生成的中間文件。

第2章 預(yù)處理 2.1 預(yù)處理的概念與作用

預(yù)處理概念:預(yù)處理器(cpp)根據(jù)以字符#開頭的命令,修改原始的C程序。比如hello.c中第1行的#include命令告訴預(yù)處理器讀取系統(tǒng)頭文件stdio.h的內(nèi)容,并把它直接插入程序文本中。結(jié)果就得到了另一個C程序,通常是以.i作為文件擴展名。

預(yù)處理作用:將頭文件的內(nèi)容插入到程序文本中,方便編譯器進行下一步的編譯。

2.2在Ubuntu下預(yù)處理的命令

命令:gcc -E hello.c -o hello.i

圖2.2Linux下預(yù)處理結(jié)果

2.3 Hello的預(yù)處理結(jié)果解析

通過分析hello.i文件內(nèi)容,代碼變成了3091行,其中main函數(shù)占3078-3091行,文件前面插入了被#include的系統(tǒng)頭文件。

2.4 本章小結(jié)

本節(jié)獲取了預(yù)處理后的hello.i文件,并據(jù)其分析了預(yù)處理的過程。

第3章 編譯 3.1 編譯的概念與作用

編譯概念:編譯器(ccl)將文本文件hello.i翻譯成文本文件hello.s,它包含一個匯編語言程序,該程序包含函數(shù)main的定義。

編譯作用:它為不同高級語言的不同編譯器提供了通用的輸出語言。

3.2 在Ubuntu下編譯的命令

命令:gcc -S hello.i -o hello.s

圖3.2Linux下編譯結(jié)果

3.3 Hello的編譯結(jié)果解析

3.3.1數(shù)據(jù)

(1)字符串

只讀字符串,在.rodata中聲明

(2)數(shù)組

Main函數(shù)讀取參數(shù)時,argv作為存放 char指針的數(shù)組同時是第二個參數(shù)傳入。

3.3.2賦值

使用mov指令,如圖:

movl后綴代表數(shù)據(jù)大小為4個字節(jié),將0賦值到%eax中。

3.3.3算術(shù)操作

使用算術(shù)操作指令進行算數(shù)操作,如圖:

此處addl將%rbp-4地址處的值加了1。

3.3.4關(guān)系操作

使用 cmp指令進行比較,如圖:

cmpl對應(yīng)源代碼i與8比較,jle代表i<=8時,跳轉(zhuǎn)至L4循環(huán)體。

3.3.5函數(shù)操作

(1)參數(shù)傳遞

函數(shù)調(diào)用參數(shù)傳遞規(guī)則:第1~6個參數(shù)依次儲存在%rdi、%rsi、%rdx、%rcx、%r8、%r9寄存器中,剩下的參數(shù)通過棧傳遞。

(2)函數(shù)調(diào)用

使用call指令調(diào)用函數(shù),call后接函數(shù)名稱,如圖:

表示調(diào)用printf函數(shù)。

3.4 本章小結(jié)

本節(jié)獲取了編譯后的hello.s文件,并據(jù)其分析了編譯的過程。

第4章 匯編 4.1 匯編的概念與作用

匯編概念:匯編器(as)將hello.s翻譯成機器語言指令,把這些指令打包成一種叫做可重定位目標(biāo)程序的格式,并將結(jié)果保存在目標(biāo)文件hello.o中。

匯編作用:將文本文件翻譯為機器可讀懂的二進制文件,以便于執(zhí)行鏈接。

4.2 在Ubuntu下匯編的命令

gcc -c hello.s -o hello.o

圖4.2Linux下匯編結(jié)果

4.3 可重定位目標(biāo)elf格式

指令:readelf -a hello.o >./elf.txt

4.3.1ELF頭

包含信息為文件結(jié)構(gòu)的說明信息:16字節(jié)的標(biāo)識信息,文件類型,機器類型,節(jié)頭表偏移,節(jié)頭表的表項大小,表項個數(shù),生成該文件的系統(tǒng)字大小和字節(jié)順序

4.3.2節(jié)頭部表

節(jié)頭部表描述不同節(jié)的位置和大小信息,其中目標(biāo)文件的每個節(jié)都有一個固定大小的條目。

4.3.3重定位節(jié)

包含重定位的信息,鏈接時鏈接器把這個目標(biāo)文件和其他文件組合時,進行重定位并根據(jù)信息修改位置。

4.4 Hello.o的結(jié)果解析

指令:objdump -d -r hello.o

操作數(shù):hello.s中操作數(shù)為十進制,反匯編代碼中操作數(shù)為十六進制。

分支轉(zhuǎn)移:反匯編代碼中的跳轉(zhuǎn)指令不再使用段名稱如L0、L1等,而是采用跳轉(zhuǎn)到指定地址的方式進行跳轉(zhuǎn)。

4.5 本章小結(jié)

本節(jié)獲取了匯編后的hello.o文件,并獲得ELF格式,最后分析了匯編代碼與反匯編代碼的區(qū)別。

第5章 鏈接 5.1 鏈接的概念與作用

鏈接概念: C編譯器提供的標(biāo)準C庫中的函數(shù)存在于一個單獨的預(yù)編譯好了的目標(biāo)文件中,鏈接器(ld)負責(zé)合并這個文件到我們的hello.o程序中。

鏈接作用:將獨立的可重定位目標(biāo)模塊組織成統(tǒng)一的可執(zhí)行目標(biāo)文件。

5.2 在Ubuntu下鏈接的命令

命令:ld -o hello -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o hello.o /usr/lib/x86_64-linux-gnu/libc.so /usr/lib/x86_64-linux-gnu//crtn.o

圖5.2Linux下匯編結(jié)果

5.3 可執(zhí)行目標(biāo)文件hello的格式

命令:readelf -a hello >helloelf.txt

5.3.1ELF頭

5.3.2節(jié)頭部表

從節(jié)頭部表可以得到每個節(jié)的位置和大小信息,比如.dynsym節(jié)的開始位置是0x400480,大小為67個字節(jié)

5.3.3程序頭

5.4 hello的虛擬地址空間

圖5.4Linux系統(tǒng)edb中的hello程序

分析:從data dump中初始位置為0x401000,與5.3節(jié)中程序的入口點.init節(jié)起始位置相同

5.5 鏈接最后分析了匯編代碼與反匯編代碼的重定位過程分析

指令:objdump -d -r hello

圖5.5 hello反匯編代碼

分析:hello的反匯編代碼加入了其他庫函數(shù)(如printf),故代碼量比hello.o長,而且由于hello無需再重定位,因此hello中的地址為虛擬內(nèi)存地址。

鏈接過程中動態(tài)鏈接器為函數(shù)定義了程序入口_start、初始化函數(shù)_init,_start 程序調(diào)用main函數(shù)并鏈接庫函數(shù),鏈接器將這些函數(shù)鏈接到一起使程序能夠最終執(zhí)行。

重定位過程中鏈接器首先將所有相同類型的節(jié)合并成為同一類型的新節(jié),合并完成后該新節(jié)即為可執(zhí)行文件hello的.data節(jié)。之后鏈接器再分配內(nèi)存地址賦給新的節(jié)和輸入模塊定義的節(jié)以及符號。

5.6 hello的執(zhí)行流程

使用edb執(zhí)行hello,程序初始位置位于0x7f5caf5c22b0

1. 從加載到進入main函數(shù)的過程

開始時,經(jīng)過一系列執(zhí)行,程序首先跳轉(zhuǎn)到子程序_start,該子程序位于地址4010f0處。隨后通過callq *0x2ed2(%rip) 指令跳轉(zhuǎn)到位于地址0x7f38faffefc0的“Libc-2.31.so!_libc_start_main”子程序,在子程序中,通過call *%rax指令跳轉(zhuǎn)到main函數(shù),地址為0x401125。

2. 從main函數(shù)到程序執(zhí)行完

進入main函數(shù),程序按照源代碼順序依次執(zhí)行,在執(zhí)行的過程中分別調(diào)用不同的子程序,子程序名稱和地址如下:

401090

4010a0

4010b0

4010c0

4010d0

4010e0

5.7 Hello的動態(tài)鏈接分析

首先,根據(jù)節(jié)頭部表找到GOT表地址,由圖可知其在0x403ff0。

在edb的data dump中定位0x403ff0地址

由結(jié)果可知在dl_init前后,0x403ff0 處和0x404000 處的8bit數(shù)據(jù)分別由000000000000變?yōu)榱薱07d74c57b7f 和e03299c57b7f,GOT[1]指向重定位表,作用是確定調(diào)用函數(shù)的地址,GOT[2]指向動態(tài)鏈接器ld-linux.so運行時地址

5.8 本章小結(jié)

本節(jié)介紹了鏈接的概念和作用,同時分析了hello程序的虛擬地址空間、重定位過程、執(zhí)行流程、動態(tài)鏈接過程。

第6章 hello進程管理 6.1 進程的概念與作用 ?????? 進程概念:進程的經(jīng)典定義就是一個執(zhí)行中程序的實例,是操作系統(tǒng)對一個正在運行程序的抽象。 ?????? 進程作用:進程提供給應(yīng)用程序的關(guān)鍵抽象;一個獨立的邏輯控制流,如同程序獨占處理器;一個私有的地址空間,如同程序獨占內(nèi)存系統(tǒng) 6.2 簡述殼Shell-bash的作用與處理流程

作用:shell提供了一個界面,它解釋用戶輸入的命令并將它送入內(nèi)核。

處理流程:shell從終端讀入指令,將輸入的字符串切分獲得全部參數(shù),首先判斷指令是否為內(nèi)部指令,內(nèi)部指令將被執(zhí)行,否則檢查是否為一個可執(zhí)行文件。如果兩者都不是,shell將顯示一個錯誤信息。

6.3 Hello的fork進程創(chuàng)建過程

執(zhí)行./hello后,bash解析此條命令,發(fā)現(xiàn)./hello不是bash內(nèi)置命令,于是在當(dāng)前目錄嘗試尋找并執(zhí)行hello文件。此時bash調(diào)用fork函數(shù)創(chuàng)建一個子進程,子進程與得到一份與父進程用戶級虛擬空間相同且獨立的副本——包括數(shù)據(jù)段、代碼、共享庫、堆和用戶棧。二者間的PID不相同,fork函數(shù)會返回兩次,在父進程中,返回子進程的PID,在子進程中,返回0。

6.4 Hello的execve過程

execve開始執(zhí)行hello有以下4個步驟:

1.刪除已存在的用戶區(qū)域。刪除當(dāng)前進程虛擬地址的用戶部分中的已存在的區(qū)域結(jié)構(gòu)。即刪除之前shell運行時已經(jīng)存在的區(qū)域結(jié)構(gòu)。

2.映射私有區(qū)域。為hello的代碼、數(shù)據(jù)、bss和棧區(qū)域創(chuàng)建新的區(qū)域結(jié)構(gòu)。所有這些新的區(qū)域都是私有的、寫時復(fù)制的。代碼和數(shù)據(jù)區(qū)域被映射為hello文件中的.text 和.data區(qū)。bss區(qū)域是請求二進制零的,映射到匿名文件,其大小包含在hello中。棧和堆區(qū)域也是請求二進制零的,初始長度為零。

3.映射共享區(qū)域。hello程序與共享對象鏈接,比如標(biāo)準C庫1ibc.so,那么這些對象都是動態(tài)鏈接到這個程序的,然后再映射到用戶虛擬地址空間中的共享區(qū)域內(nèi)。

4.設(shè)置程序計數(shù)器(PC)。最后,execve設(shè)置當(dāng)前進程上下文中的程序計數(shù)器,使之指向代碼區(qū)域的人口點。

6.5 Hello的進程執(zhí)行

當(dāng)我們讓它運行hello程序時,shell通過系統(tǒng)調(diào)用,來執(zhí)行我們的請求,系統(tǒng)調(diào)用會將控制權(quán)傳遞給操作系統(tǒng)。操作系統(tǒng)保存shell進程的上下文,創(chuàng)建一個新的hello進程及其上下文,然后將控制權(quán)傳給新的hello進程。在hello進程的執(zhí)行過程中,在某些時刻,hello程序調(diào)用sleep函數(shù)顯式請求進程休眠,此時內(nèi)核執(zhí)行上下文切換,從用戶模式轉(zhuǎn)換到內(nèi)核模式,搶占hello進程。隨后,在其他進程執(zhí)行一段時間后,內(nèi)核做出決定將控制返回給hello進程繼續(xù)執(zhí)行。如此反復(fù)直到hello進程終止后,操作系統(tǒng)恢復(fù)shell進程的上下文,并將控制權(quán)傳給它,shell進程會繼續(xù)等待下一個命令行輸入

6.6 hello的異常與信號處理

異常:hello執(zhí)行過程中會出現(xiàn)異步中斷異常和系統(tǒng)調(diào)用,中斷即來自外部I/O設(shè)備的信號打斷進程。

信號:會產(chǎn)生諸如SIGINT,SIGQUIT,SIGTSTP等信號。

運行處理:

6.6.1不停亂按(包括回車)

只是在屏幕上顯示出來并未對程序的輸出造成影響

6.6.2輸入CTRL+Z

向內(nèi)核發(fā)送信號SINGINT,陷入到內(nèi)核態(tài),處理信號,該命令為將進程掛起并顯示處理結(jié)果。

輸入ps可查看進程

輸入jobs列出jobs可知進程處于停止?fàn)顟B(tài)

輸入pstree

輸入fg繼續(xù)前臺進程

對比輸入kill前后hello進程被殺死

6.6.3輸入CTRL+C

向內(nèi)核發(fā)送信號SINGINT,陷入到內(nèi)核態(tài),處理信號,終止程序

6.7本章小結(jié)

本節(jié)從進程、異常、上下文的角度分析了hello的執(zhí)行過程,以及在執(zhí)行過程中程序?qū)Ξ惓5奶幚砹鞒獭?/p>第7章 hello的存儲管理 7.1 hello的存儲器地址空間

邏輯地址: cpu執(zhí)行程序過程中的一種中間地址。一個邏輯地址,是由一個段標(biāo)識符加上一個指定段內(nèi)的相對地址的偏移量。

線性地址:是邏輯地址到物理地址變換之間的中間層。程序代碼會產(chǎn)生邏輯地址,或者說是段中的偏移地址,加上相應(yīng)段的基地址就生成了一個線性地址。

虛擬地址:是相對于物理內(nèi)存對整個內(nèi)存的抽象描述。有了這樣的抽象,一個程序可以使用比真實物理地址大得多的地址空間,多個進程可以使用相同的地址。

物理地址: 用于內(nèi)存芯片級的單元尋址,與地址總線相對應(yīng)。

7.2 Intel邏輯地址到線性地址的變換-段式管理 ?????? 邏輯地址是程序源碼編譯后所形成的,跟實際內(nèi)存沒有直接聯(lián)系的地址,即在不同的機器上,使用相同的編譯器來編譯同一個源程序,則其邏輯地址是相同的。 ???? 線性地址=段基址*16+偏移的邏輯地址,而段基址由于不同的機器其任務(wù)不同,其所分配的段基址(線性地址)也會不相同,因此,其線性地址會不同。 7.3 Hello的線性地址到物理地址的變換-頁式管理

線性地址對應(yīng)到物理地址是通過分頁機制,即通過頁表查找來對應(yīng)物理地址。

分頁是CPU提供的一種機制,Linux根據(jù)這種機制的規(guī)則,利用它實現(xiàn)了內(nèi)存管理。在保護模式下,控制寄存器的最高位PG位控制著分頁管理機制是否生效,如果PG=1,分頁機制生效,需通過頁表查找才能把線性地址轉(zhuǎn)換物理地址。

分頁的基本原理是把內(nèi)存劃分成大小固定的若干單元,每個單元稱為一頁,每頁包含4k字節(jié)的地址空間。這樣每一頁的起始地址都是4k字節(jié)對齊的。為了能轉(zhuǎn)換成物理地址,我們需要給CPU提供當(dāng)前任務(wù)的線性地址轉(zhuǎn)物理地址的查找表,即頁表。x86將線性地址通過頁目錄表和頁表兩級查找轉(zhuǎn)換成物理地址。

7.4 TLB與四級頁表支持下的VA到PA的變換

一到三級頁表中存放的數(shù)據(jù)是指向下一級頁表的首地址,而不是物理頁號。逐步訪問到第四級頁表,第四級頁表中裝的就是物理頁號,通過第四級頁表讀出的物理頁號鏈接上虛擬地址中的VPO獲得物理地址。用頁表進行虛實地址轉(zhuǎn)化的基本原理如下圖:

7.5 三級Cache支持下的物理內(nèi)存訪問

首先是CPU發(fā)出一個虛擬地址給TLB里面搜索,如果命中的話就直接先發(fā)送到L1cache里面,沒有命中的話就先在頁表里面找到以后再發(fā)送過去,到了L1里面以后,尋找物理地址又要檢測是否命中。

7.6 hello進程fork時的內(nèi)存映射

當(dāng)fork 函數(shù)被shell調(diào)用時,內(nèi)核為hello進程創(chuàng)建各種數(shù)據(jù)結(jié)構(gòu),并分配給它一個唯一的PID 。并且創(chuàng)建hello進程的mm_struct、區(qū)域結(jié)構(gòu)和頁表的原樣副本。它將兩個進程中的每個頁面都標(biāo)記為只讀,并將兩個進程中的每個區(qū)域結(jié)構(gòu)都標(biāo)記為私有的寫時復(fù)制。當(dāng)這兩個進程中的任一一個后來進行寫操作時,寫時復(fù)制機制就會創(chuàng)建新頁面,因此,也就為每個進程保持了私有地址空間的抽象概念。

7.7 hello進程execve時的內(nèi)存映射

1.刪除已存在的用戶區(qū)域。刪除當(dāng)前進程虛擬地址的用戶部分中的已存在的區(qū)域結(jié)構(gòu)。即刪除之前shell運行時已經(jīng)存在的區(qū)域結(jié)構(gòu)。

2.映射私有區(qū)域。為hello的代碼、數(shù)據(jù)、bss和棧區(qū)域創(chuàng)建新的區(qū)域結(jié)構(gòu)。所有這些新的區(qū)域都是私有的、寫時復(fù)制的。代碼和數(shù)據(jù)區(qū)域被映射為hello文件中的.text 和.data區(qū)。

3.映射共享區(qū)域。hello程序與共享對象鏈接,比如標(biāo)準C庫1ibc.so,那么這些對象都是動態(tài)鏈接到這個程序的,然后再映射到用戶虛擬地址空間中的共享區(qū)域內(nèi)。

4.設(shè)置程序計數(shù)器(PC)。最后,execve設(shè)置當(dāng)前進程上下文中的程序計數(shù)器,使之指向代碼區(qū)域的人口點。

7.8 缺頁故障與缺頁中斷處理

在請求分頁系統(tǒng)中,可以通過查詢頁表中來確定所要訪問的頁面是否存在于內(nèi)存中。每當(dāng)所要訪問的頁面不在內(nèi)存時,會產(chǎn)生一次缺頁中斷,此時操作系統(tǒng)會根據(jù)頁表中的外存地址在外存中找到所缺的一頁,并將其調(diào)入內(nèi)存。

處理:選擇一個犧牲頁面,如果這個犧牲頁面被修改過,那么就將它換入新的頁面并更新頁表。當(dāng)缺頁處理程序返回時,CPU 重新啟動引起缺頁的指令。

7.9動態(tài)存儲分配管理

在程序運行時程序員使用動態(tài)內(nèi)存分配器獲得虛擬內(nèi)存,動態(tài)內(nèi)存分配器維護著一個進程的虛擬內(nèi)存區(qū)域,稱為堆。分配器將堆視為一組不同大小的塊的集合,每個塊要么是已分配的,要么是空閑的。分配器的類型有顯示分配和隱式分配,前者要求應(yīng)用顯式地釋放任何已分配的塊,后者應(yīng)用檢測到已分配塊不再被程序所使用,就釋放這個塊。

7.10本章小結(jié)

本節(jié)分析了hello的存儲器空間,并給出了 TLB與四級頁表支持下的VA與 PA的變換和三級Cache支持下的物理內(nèi)存訪問過程的介紹。

第8章 hello的IO管理 8.1 Linux的IO設(shè)備管理方法

設(shè)備的模型化:文件

設(shè)備管理:unix io接口

所有的I/ O 設(shè)備(例如網(wǎng)絡(luò)、磁盤和終端)都被模型化為文件,而所有的輸入和輸出都被當(dāng)作對相應(yīng)文件的讀和寫來執(zhí)行。這種將設(shè)備映射為文件的方式,允許Linux 內(nèi)核引出一個簡單、低級的應(yīng)用接口,稱為Unix I/O,這使得所有的輸入和輸出都能以一種統(tǒng)一且一致的方式來執(zhí)行,這就是Unix I/O接口。

8.2 簡述Unix IO接口及其函數(shù)

Linux/unix IO接口:

  1. 打開文件:返回一個小的非負整數(shù),即描述符。用描述符來標(biāo)識文件。
  2. 改變當(dāng)前文件位置 從文件開頭起始的字節(jié)偏移量。系統(tǒng)內(nèi)核保持一個文件位置k,對于每個打開的文件,起始值為0。
  3. 讀寫文件:一個讀操作就是從文件復(fù)制n>0個字節(jié)到內(nèi)存,從當(dāng)前文件位置k開始,然后將k增加到k+n。寫操作就是從內(nèi)存復(fù)制n>0個字節(jié)到一個文件,從當(dāng)前文件位置k開始,然后更新k。
  4. 關(guān)閉文件:當(dāng)應(yīng)用完成了對文件的訪問之后,它就通知內(nèi)核關(guān)閉這個文件。

函數(shù):

Open()-打開一個已經(jīng)存在的文件或是創(chuàng)建一個新文件

Read()-從文件讀取數(shù)據(jù),執(zhí)行輸出

Write()-從文件中讀取數(shù)據(jù),執(zhí)行輸出

Close()-關(guān)閉一個被打開的文件

Lseek()-用于在指定的文件描述符中將文件指針定位到相應(yīng)位置

8.3 printf的實現(xiàn)分析

printf()函數(shù)將變長參數(shù)的指針arg作為參數(shù),傳給vsprintf函數(shù)。然后vsprintf函數(shù)解析格式化字符串,調(diào)用write()函數(shù)。在write函數(shù)中,將棧中參數(shù)放入寄存器,ecx是字符個數(shù),ebx存放第一個字符地址,最后,write函數(shù)調(diào)用syscall(int INT_VECTOR_SYS_CALL)。syscall將字符串中的字節(jié)從寄存器中通過總線復(fù)制到顯卡的顯存中,顯存中存儲的是字符的ASCII碼。字符顯示驅(qū)動子程序?qū)⑼ㄟ^ ASCII 碼在字模庫中找到點陣信息將點陣信息存 儲到 vram 中。顯示芯片會按照一定的刷新頻率逐行讀取 vram,并通過信號線向液晶顯示器傳輸每一個點(RGB 分量),最終打印出了我們需要的字符串。

8.4 getchar的實現(xiàn)分析

異步異常-鍵盤中斷的處理:鍵盤中斷處理子程序。接受按鍵掃描碼轉(zhuǎn)成ascii碼,保存到系統(tǒng)的鍵盤緩沖區(qū)。

getchar等調(diào)用read系統(tǒng)函數(shù),通過系統(tǒng)調(diào)用讀取按鍵ascii碼,直到接受到回車鍵才返回。

8.5本章小結(jié)

本節(jié)主要介紹了 Linux 的 IO 設(shè)備管理方法、Unix IO 接口及其函數(shù),簡單分析了 printf 函數(shù)和 getchar 函數(shù)的實現(xiàn)。

結(jié)論

hello程序所經(jīng)歷的過程:

1.編寫:程序員通過鍵盤輸入可得hello.c(program)c語言源程序。

2.預(yù)處理:hello.c在預(yù)處理器(cpp)處理后得到hello.i。

3.編譯:通過編譯器(ccl),得到匯編程序hello.s。

4.匯編:通過匯編器(as),得到可重定位的目標(biāo)程序hello.o。

5.鏈接:通過鏈接器(ld)得到可執(zhí)行的目標(biāo)程序hello(process)。

6.運行:在shell命令行輸入./hello 2021112660 孫吳錫 3運行程序。

7.創(chuàng)建子進程:shell調(diào)用fork函數(shù)創(chuàng)建子進程。

8.運行程序:調(diào)用execve將程序加載進去。

9.結(jié)束:shell父進程回收子進程,內(nèi)核刪除為這個進程創(chuàng)建的所有數(shù)據(jù)結(jié)構(gòu)。

感悟:

即使最簡單的一個hello程序,其執(zhí)行處理的過程也是非常復(fù)雜的,要想真正理解他要花費很大的功夫,我從中學(xué)到了預(yù)處理、編譯、匯編、鏈接、進程管理、存儲管理、IO管理的相關(guān)知識,這次的課程讓我獲益匪淺。

附件

列出所有的中間產(chǎn)物的文件名,并予以說明起作用。

hello.c-程序員編寫的c語言源程序

hello.i-預(yù)處理后的源程序

hello.s-編譯后的匯編程序

hello.o-匯編后的可重定位的目標(biāo)文件

hello-鏈接后的可執(zhí)行文件

elf.txt- hello.o的elf格式文件

helloelf.txt- hello的elf格式文件

參考文獻

[1]? 林來興. 空間控制技術(shù)[M]. 北京:中國宇航出版社,1992:25-42.

[2]? 辛希孟. 信息技術(shù)與信息服務(wù)國際研討會論文集:A集[C]. 北京:中國科學(xué)出版社,1999.

[3]? 趙耀東. 新時代的工業(yè)工程師[M/OL]. 臺北:天下文化出版社,1998 [1998-09-26]. http://www.ie.nthu.edu.tw/info/ie.newie.htm(Big5).

[4]? 諶穎. 空間交會控制理論與方法研究[D]. 哈爾濱:哈爾濱工業(yè)大學(xué),1992:8-13.

[5]? KANAMORI H. Shaking Without Quaking[J]. Science,1998,279(5359):2063-2064.

[6]? CHRISTINE M. Plant Physiology: Plant Biology in the Genome Era[J/OL]. Science,1998,281:331-332[1998-09-23]. http://www.sciencemag.org/cgi/ collection/anatmorp.

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)站題目:程序人生-Hello’sP2P-創(chuàng)新互聯(lián)
標(biāo)題網(wǎng)址:http://jinyejixie.com/article34/issse.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT建站公司、企業(yè)建站、虛擬主機手機網(wǎng)站建設(shè)、商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化
绍兴县| 池州市| 桂东县| 渝北区| 奈曼旗| 桂阳县| 衡南县| 札达县| 武定县| 西安市| 中江县| 凯里市| 凯里市| 泰安市| 庄河市| 吴忠市| 邵阳县| 连城县| 米泉市| 嘉鱼县| 平山县| 台江县| 闻喜县| 南宁市| 江都市| 阳朔县| 孟村| 瑞昌市| 夏邑县| 北票市| 仁化县| 武乡县| 泗洪县| 海阳市| 庆云县| 忻城县| 雅江县| 榆林市| 沿河| SHOW| 东山县|