目錄
?
2.3 Hello的預(yù)處理結(jié)果解析 - 5 -
5.3可執(zhí)行目標(biāo)文件hello的格式 - 8 -
6.2簡述殼Shell-bash的作用與處理流程 - 10 -
6.3 Hello的fork進(jìn)程創(chuàng)建過程 - 10 -
6.5 Hello的進(jìn)程執(zhí)行 - 10 -
7.2 Intel邏輯地址到線性地址的變換-段式管理 - 11 -
7.3 Hello的線性地址到物理地址的變換-頁式管理 - 11 -
7.4 TLB與四級頁表支持下的VA到PA的變換 - 11 -
7.5三級Cache支持下的物理內(nèi)存訪問 - 11 -
7.6 hello進(jìn)程fork時(shí)的內(nèi)存映射 - 11 -
7.7 hello進(jìn)程execve時(shí)的內(nèi)存映射 - 11 -
8.1 Linux的IO設(shè)備管理方法 - 13 -
8.2簡述Unix IO接口及其函數(shù) - 13 -
8.3 printf的實(shí)現(xiàn)分析 - 13 -
8.4 getchar的實(shí)現(xiàn)分析 - 13 -
?
1.1 Hello簡介
P2P即 From Program to Process,是將源程序hello.c(Program),在OS(比如linux)中進(jìn)行預(yù)處理(cpp處理器),編譯(cll),匯編(as)這三個(gè)過程剃根,再鏈接生成可執(zhí)行文件更啄,得到可執(zhí)行的hello的過程找田。
O2O是指在終端中輸入“./hello”運(yùn)行可執(zhí)行文件,此時(shí)shell會為它創(chuàng)建一個(gè)新的子進(jìn)程控轿,為其execve映射虛擬內(nèi)存,程序完成之后溶浴,shell父進(jìn)程回收子進(jìn)程恢復(fù)原本的hello進(jìn)程,這就是O2O的過程
1.2 環(huán)境與工具
硬件:Intel Core i5管引,6G RAM 1T HDD
軟件:Windows10士败,Ubuntu 18.04.1
開發(fā)與調(diào)試工具:gedit、vim汉匙、gcc拱烁、edb、readelf噩翠、hexedit
列出你為編寫本論文戏自,生成的中間結(jié)果文件的名字,文件的作用等伤锚。
hello.c :用C語言編寫的hello程序源代碼hello.i : ?hello.c經(jīng)預(yù)處理處理得到的文本文件hello.s :編譯hello.i后得到的匯編代碼hello.o :匯編hello.s后得到的可重定位目標(biāo)執(zhí)行文件hello : ?hello.o鏈接后得到的二進(jìn)制文件
本章中簡單的用文字介紹了P2P和O2O的整個(gè)過程擅笔,并介紹了即將運(yùn)用的開發(fā)工具和所處的開發(fā)環(huán)境。
(第1章0.5分)
2.1?預(yù)處理的概念與作用
概念:在進(jìn)行編譯之前,將hello.c首先翻譯成一個(gè)由ASCII碼構(gòu)成的中間文件hello.i猛们,預(yù)處理會從宏定義(#define)念脯,源文件包含(#include),條件編譯(#if ?#ifdef ?#ifndef ?#else ?#elif ?#endif)等方面進(jìn)行弯淘。主要處理那些用“#”開頭的指令绿店。
作用:預(yù)處理指令一般被用來使源代碼在不同的執(zhí)行環(huán)境中被方便的修改或者編譯。
圖2-2-1預(yù)處理命令行
圖2-2-2 ?hello.i打開圖(部分)
圖2-2-3 ?hello.i打開圖(部分)
預(yù)處理之后的文件達(dá)到了3042行庐橙,源文件中的代碼出現(xiàn)在在文件的末尾假勿,頭文件被引入,以“#”起始的行被展開态鳖,文件開頭的注釋“// 大作業(yè)的 hello.c 程序”等等內(nèi)容被刪除转培。
本章中介紹了預(yù)處理的基本概念和作用,介紹了hello.c的預(yù)處理命令浆竭,給出了預(yù)處理后文件的部分截圖浸须,并且對hello.i進(jìn)行了簡單的分析
(第2章0.5分)
概念:利用編譯程序從源語言(C語言)編寫的源程序產(chǎn)生目標(biāo)程序(匯編語言程序)的過程,?編譯程序把一個(gè)源程序翻譯成目標(biāo)程序的工作過程分為五個(gè)階段:詞法分析邦泄;語法分析删窒;語義檢查和中間代碼生成;代碼優(yōu)化虎韵;目標(biāo)代碼生成易稠。
在本文中可以解釋成檢查hello.i是否有錯(cuò)誤,無錯(cuò)誤將其翻譯成匯編語言包蓝,生成hello.s驶社。
作用:在本文中是將源代碼轉(zhuǎn)換稱為匯編代碼
注意:這兒的編譯是指從.i到 .s 即預(yù)處理后的文件到生成匯編語言程序
圖3-2-1編譯的命令行
下面的圖是按照順序?qū)ello.s的各部分截圖粘貼
圖3-3-1
file:源文件名
.text:代碼段
.section ?.rodata:rodata節(jié)
.align:對齊方式
.global全局變量
.string:字符串
.type:指定對象類型或函數(shù)類型
圖3-3-2
①匯編語言中各種數(shù)據(jù)是通過立即數(shù)的形式存儲的。比如在上圖中可以看出main函數(shù)的參數(shù)argc在%edi內(nèi)保存测萎,儲存在-20(%rbp)內(nèi) 亡电。
②
使用了加載有效地址指令leaq計(jì)算LC1的段地址%rip+.LC1并傳遞給%rdi
③
部分比較argc和4的大小,相等就跳到L2繼續(xù)程序硅瞧,不相等則執(zhí)行下一步程序【源代碼中if(argc!=4)的部分】份乒。
④
調(diào)用printf()函數(shù)。
⑤
把返回值設(shè)定為1(說明存在異常)腕唧,并且調(diào)用exit()函數(shù)退出程序或辖,給exit()函數(shù)傳入的參數(shù)值是1。
圖3-3-3
⑥給i賦值為0枣接,并保存在-4(%rbp)內(nèi)颂暇,然后執(zhí)行L3部分的程序
圖3-3-4
⑦
調(diào)用printf()函數(shù)
⑧
調(diào)用atoi()函數(shù)
⑨
調(diào)用sleep()函數(shù)
⑩
i=i+1實(shí)現(xiàn)源代碼中的i++
圖3-3-5
(11)
判斷i和7的關(guān)系,如果i小于等于7但惶,則執(zhí)行L4的代碼耳鸯。從而實(shí)現(xiàn)了循環(huán)功能【源代碼中for(i=0;i<8;i++)的部分】
(12)
調(diào)用getchar()函數(shù)湿蛔。
(13)
設(shè)置返回值為0,退出程序县爬。
圖3-3-6
本章主要講述了編譯的作用和概念阳啥,hello.s匯編代碼的生成方法和具體內(nèi)容,并且對hello.s中匯編語言是如何表示高級語言的做了簡單的分析财喳。
(第3章2分)
概念:as(編譯器)把匯編語言代碼翻譯成和它相對應(yīng)的機(jī)器語言指令察迟,并且這些指令將被打包成為可重定位目標(biāo)文件,這個(gè)過程就是匯編纲缓。
作用:把匯編語言轉(zhuǎn)換成機(jī)械語言以供計(jì)算機(jī)識別
注意:這兒的匯編是指從.s到 .o 即編譯后的文件到生成機(jī)器語言二進(jìn)制程序的過程卷拘。
圖4-2-1匯編的指令行
分析hello.o的ELF格式喊废,用readelf等列出其各節(jié)的基本信息祝高,特別是重定位項(xiàng)目分析。
污筷。
圖4-3-1 elf文件頭
圖4-3-2 hello.o各節(jié)的詳細(xì)信息
圖4-3-3 hello.o的可重定位信息
圖4-3-4 hello.o的各節(jié)基本信息
由上面的圖我們可以看出hello.o文件是可重定位文件工闺,采用補(bǔ)碼和小端存儲。
ELF頭(圖4-3-1)包括類別(Class),數(shù)據(jù)(Data)瓣蛀,機(jī)器類型(Machine)陆蟆,入口點(diǎn)地址(Start of program headers),程序頭起點(diǎn)地址(Start of section headers)惋增,本頭大小叠殷,節(jié)頭部大小等信息。
(以下格式自行編排诈皿,編輯時(shí)刪除)
objdump -d -r hello.o分析hello.o的反匯編林束,并請與第3章的 hello.s進(jìn)行對照分析。
說明機(jī)器語言的構(gòu)成稽亏,與匯編語言的映射關(guān)系壶冒。特別是機(jī)器語言中的操作數(shù)與匯編語言不一致,特別是分支轉(zhuǎn)移函數(shù)調(diào)用等截歉。
圖4-4 hello.o的反匯編
①機(jī)器語言是二進(jìn)制的機(jī)器指令胖腾,機(jī)器指令由操作碼和操作數(shù)組成。
②每一條匯編語言都有一條機(jī)器語言和它相對應(yīng)瘪松,反之亦然咸作。
③不同之處的分析:
[if !supportLists](1)[endif]hello.s中立即數(shù)采用10進(jìn)制形式,hello.o的反匯編中采用16進(jìn)制
[if !supportLists](2)[endif]分支轉(zhuǎn)移:hello.o的反匯編中用指令地址代替L1,L2等跳轉(zhuǎn)目標(biāo)的名稱宵睦。
[if !supportLists](3)[endif]函數(shù)調(diào)用:hello.s中調(diào)用函數(shù)使用函數(shù)的名稱记罚,hello.o的反匯編中函數(shù)調(diào)用的目標(biāo)是一個(gè)指令地址。
[if !supportLists](4)[endif]hello.o的反匯編中全局變量和常量已經(jīng)被存在一個(gè)具體的地址里状飞,調(diào)用時(shí)在具體的地址里存取毫胜。
介紹了匯編的基本概念和作用书斜,以及將hello.s匯編成為hello.o的方法。分析了hello.o的ELF格式酵使,查看了各節(jié)的信息和hello.o的可重定位信息荐吉。
列出了hello.o的反匯編文件內(nèi)容,分析了機(jī)器語言和匯編語言的關(guān)系口渔。對比探討了hello.s與hello.o的區(qū)別样屠。
(第4章1分)
(以下格式自行編排,編輯時(shí)刪除)
概念:將各種代碼和數(shù)據(jù)片段收集并組合成為一個(gè)可以在終端下“./文件名”執(zhí)行的單一的文件的過程
作用:把各個(gè)代碼和數(shù)據(jù)片段整合缺脉,得到一個(gè)可以執(zhí)行的文件痪欲。
注意:這兒的鏈接是指從hello.o到hello生成過程。
(以下格式自行編排攻礼,編輯時(shí)刪除)
圖5-2-1鏈接指令
圖5-2-2鏈接后的文件夾
圖中hello就是鏈接成的文件
5.3 可執(zhí)行目標(biāo)文件hello的格式
分析hello的ELF格式业踢,用readelf等列出其各段的基本信息,包括各段的起始地址礁扮,大小等信息知举。
圖5-3-1 elf文件頭信息
圖5-3-2 elf節(jié)基本信息
由上面的圖可以看出hello屬于可執(zhí)行文件,使用補(bǔ)碼和小端存儲太伊。
使用edb加載hello雇锡,再Plugins - SymbolViewer就可以查看本進(jìn)程的虛擬地址空間的信息。
比如說
和
圖紙中紅線標(biāo)出地方對比
我們可以的發(fā)現(xiàn)兩者顯示的init段的起始地址均為0x0000000000401000僚焦,是相同的锰提。
再比如
和
對比,發(fā)現(xiàn)rodata的起始地址也是相同的芳悲。
(以下格式自行編排立肘,編輯時(shí)刪除)
objdump -d -r hello分析hello與hello.o的不同,說明鏈接的過程芭概。
結(jié)合hello.o的重定位項(xiàng)目赛不,分析hello中對其怎么重定位的。
(以下格式自行編排罢洲,編輯時(shí)刪除)
使用edb執(zhí)行hello踢故,說明從加載hello到_start,到call main,以及程序終止的所有過程惹苗。請列出其調(diào)用與跳轉(zhuǎn)的各個(gè)子程序名或程序地址殿较。
加載hello之后,首先運(yùn)行一段程序如下:
然后最后的跳轉(zhuǎn)指令中儲存的是_start的地址0x0000000000401090,再運(yùn)行如下程序:
調(diào)用函數(shù)到達(dá)main函數(shù)桩蓉。
執(zhí)行main函數(shù)淋纲,本程序中途會進(jìn)入exit()函數(shù),運(yùn)行exit()函數(shù)程序終止院究。
從加載hello到_start:
跳轉(zhuǎn)到*%R12
_start到main調(diào)用和跳轉(zhuǎn)的子程序:
程序編譯時(shí)會采用兩種表進(jìn)行輔助洽瞬,一個(gè)為PLTT表本涕,一個(gè)為GOT表,PLT表可以稱為內(nèi)部函數(shù)表伙窃,GOT表為全局函數(shù)表(也可以說是動態(tài)函數(shù)表這是個(gè)人自稱)菩颖,這兩個(gè)表是相對應(yīng)的,PLT表中的數(shù)據(jù)就是GOT表中的一個(gè)地址为障,可以理解為一定是一一對應(yīng)的晦闰。
在dl_init前,初始時(shí)每個(gè)GOT條目都指向?qū)?yīng)的PLT條目的第二條指令鳍怨。
dl_init后數(shù)據(jù)應(yīng)該有改變但是本程序edb時(shí)無法執(zhí)行到那一步
本小節(jié)中介紹了hello可執(zhí)行文件的相關(guān)信息呻右,鏈接生成可執(zhí)行文件的過程以及它的反匯編語言。
(第5章1分)
概念:進(jìn)程(Process)是計(jì)算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)行活動鞋喇,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位声滥,是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ)。進(jìn)程是正在運(yùn)行的程序的實(shí)例确徙。
作用:從理論角度看醒串,是對正在運(yùn)行的程序過程的抽象;
從實(shí)現(xiàn)角度看鄙皇,是一種數(shù)據(jù)結(jié)構(gòu),目的在于清晰地刻畫動態(tài)系統(tǒng)的內(nèi)在規(guī)律仰挣,有效管理和調(diào)度進(jìn)入計(jì)算機(jī)系統(tǒng)主存儲器運(yùn)行的程序
Shell是用戶和操作系統(tǒng)之間完成交互式操作的一個(gè)接口程序伴逸。
bash是Linux操作系統(tǒng)的默認(rèn)shell程序。
處理流程:
[if !supportLists](1)[endif]判斷收到的是否是內(nèi)置命令
[if !supportLists](2)[endif]是則解析命令行
[if !supportLists](3)[endif]不是判斷是否要打開某個(gè)程序
[if !supportLists](4)[endif]搜索路徑里沒有目標(biāo)程序則報(bào)錯(cuò)
6.3 Hello的fork進(jìn)程創(chuàng)建過程
Shell調(diào)用fork()函數(shù)膘壶,父進(jìn)程創(chuàng)建一個(gè)子進(jìn)程错蝴,hello的打開是在子進(jìn)程內(nèi)進(jìn)行,子進(jìn)程不完全但是幾乎是和父進(jìn)程相同的颓芭,子進(jìn)程得到的是父進(jìn)程虛擬空間的一個(gè)副本顷锰,這個(gè)副本內(nèi)包含代碼段,數(shù)據(jù)段亡问,malloc官紫,共享區(qū)域,用戶棧等等和父進(jìn)程虛擬空間相同的內(nèi)容州藕。且這個(gè)子進(jìn)程還得到了父進(jìn)程中打開文件的副本束世。子進(jìn)程和父進(jìn)程唯一的不同是PID。
shell會調(diào)用execve()函數(shù)床玻,在創(chuàng)建好的子進(jìn)程里面加載hello程序毁涉,并且允許它進(jìn)行操作,這個(gè)函數(shù)把hello的.data節(jié)锈死,.bss節(jié)等部分的內(nèi)容都加載到了fork出的子程序的虛擬空間內(nèi)
Linux系統(tǒng)的每個(gè)程序運(yùn)行時(shí)贫堰,一定是處于一個(gè)進(jìn)程的上下文當(dāng)中的穆壕,shell運(yùn)行hello時(shí),父進(jìn)程生成一個(gè)子進(jìn)程其屏,它幾乎與父進(jìn)程一樣粱檀,子進(jìn)程再由shell調(diào)用execve把hello的數(shù)據(jù)內(nèi)容載入到子進(jìn)程的虛擬內(nèi)存當(dāng)中。新產(chǎn)生的代碼段和數(shù)據(jù)段經(jīng)過虛擬內(nèi)存映射成為可執(zhí)行文件的內(nèi)容漫玄,然后hello就能夠被執(zhí)行了茄蚯。
異常種類:中斷、終止睦优、故障渗常。
可能出現(xiàn)SIGSTP,SIGINT故障
簡單介紹了進(jìn)程的概念和作用汗盘,以及Shell-bash和hello進(jìn)程運(yùn)行的相關(guān)內(nèi)容皱碘,以及hello異常和信號處理的內(nèi)容。
(第6章1分)
邏輯地址是指在計(jì)算機(jī)體系結(jié)構(gòu)中是指應(yīng)用程序角度看到的內(nèi)存單元(memory cell)隐孽、存儲單元(storage element)癌椿、網(wǎng)絡(luò)主機(jī)(network host)的地址。比如hello.o的反匯編里就給出了這樣的一些地址
線性地址:是邏輯地址到物理地址變換之間的中間層菱阵。在分段部件中邏輯地址是段中的偏移地址踢俄,然后加上基地址就是線性地址。
虛擬地址:程序訪問存儲器所使用的邏輯地址稱為虛擬地址晴及,與實(shí)地址模式下的分段地址類似都办,虛擬地址也可以寫為“段:偏移量”的形式,這里的段是指段選擇器虑稼。
物理地址:在存儲器里以字節(jié)為單位存儲信息琳钉,為正確地存放或取得信息,每一個(gè)字節(jié)單元給以一個(gè)唯一的存儲器地址蛛倦,稱為物理地址(Physical Address)歌懒,又叫實(shí)際地址或絕對地址。
7.3 Hello的線性地址到物理地址的變換-頁式管理
頁式管理是一種內(nèi)存空間存儲管理的技術(shù)浩习,頁式管理分為靜態(tài)頁式管理和動態(tài)頁式管理静暂。將各進(jìn)程的虛擬空間劃分成若干個(gè)長度相等的頁(page),頁式管理把內(nèi)存空間按頁的大小劃分成片或者頁面(page frame)谱秽,然后把頁式虛擬地址與內(nèi)存地址建立一一對應(yīng)頁表洽蛀,并用相應(yīng)的硬件地址變換機(jī)構(gòu),來解決離散地址變換問題疟赊。頁式管理采用請求調(diào)頁或預(yù)調(diào)頁技術(shù)實(shí)現(xiàn)了內(nèi)外存存儲器的統(tǒng)一管理郊供。
cache就是高速緩存,是為了調(diào)和CPU得過快訪問速度和內(nèi)存過慢的速度的一個(gè)硬件近哟,現(xiàn)代計(jì)算機(jī)一般都有三級高速緩存驮审,L1、L2吉执、L3疯淫,訪問速度依次遞減。
讀取信息的時(shí)候一般先訪問一級cache戳玫,若沒有所需數(shù)據(jù)則向二級cache調(diào)用熙掺,二級cache沒有則向三級cache調(diào)用,三級cache向內(nèi)存調(diào)用數(shù)據(jù)量九。
7.6 hello進(jìn)程fork時(shí)的內(nèi)存映射
在shell給hello創(chuàng)建子進(jìn)程的時(shí)候适掰,內(nèi)核為這個(gè)子進(jìn)程分配了一個(gè)唯一的PID,并且創(chuàng)建了各種數(shù)據(jù)結(jié)構(gòu)荠列。然后創(chuàng)建當(dāng)前進(jìn)程的的mm_struct, vm_area_struct和頁表的原樣副本。將每個(gè)頁面都標(biāo)記為只讀且每個(gè)區(qū)域結(jié)構(gòu)(vm_area_struct)都標(biāo)記為私有的寫時(shí)復(fù)制(COW)载城。
7.7 hello進(jìn)程execve時(shí)的內(nèi)存映射
execve的過程中肌似,加載并且運(yùn)行包含在當(dāng)前可執(zhí)行目標(biāo)文件中,屬于hello的程序诉瓦。
通過刪除目前已有的子進(jìn)程用戶區(qū)數(shù)據(jù)川队,映射私有區(qū)域,利用hello的代碼段睬澡,數(shù)據(jù)段固额,bss段等等創(chuàng)建新的區(qū)域結(jié)構(gòu),再映射共享區(qū)域的內(nèi)容煞聪,最后設(shè)置一個(gè)指向hello程序的代碼的入口處的程序計(jì)數(shù)器斗躏,就可以執(zhí)行了。
缺頁中斷就是要訪問的頁不在主存昔脯,需要操作系統(tǒng)將其調(diào)入主存后再進(jìn)行訪問啄糙。在這個(gè)時(shí)候笛臣,被內(nèi)存映射的文件實(shí)際上成了一個(gè)分頁交換文件。
產(chǎn)生缺頁中斷的幾種情況:
1隧饼、當(dāng)內(nèi)存管理單元(MMU)中確實(shí)沒有創(chuàng)建虛擬物理頁映射關(guān)系沈堡,并且在該虛擬地址之后再沒有當(dāng)前進(jìn)程的線性區(qū)(vma)的時(shí)候,可以肯定這是一個(gè)編碼錯(cuò)誤燕雁,這將殺掉該進(jìn)程诞丽;
2、當(dāng)MMU中確實(shí)沒有創(chuàng)建虛擬頁物理頁映射關(guān)系拐格,并且在該虛擬地址之后存在當(dāng)前進(jìn)程的線性區(qū)vma的時(shí)候僧免,這很可能是缺頁中斷,并且可能是棧溢出導(dǎo)致的缺頁中斷禁荒;
3猬膨、當(dāng)使用malloc/mmap等希望訪問物理空間的庫函數(shù)/系統(tǒng)調(diào)用后,由于linux并未真正給新創(chuàng)建的vma映射物理頁呛伴,此時(shí)若先進(jìn)行寫操作勃痴,將和2產(chǎn)生缺頁中斷的情況一樣;若先進(jìn)行讀操作雖然也會產(chǎn)生缺頁異常热康,將被映射給默認(rèn)的零頁沛申,等再進(jìn)行寫操作時(shí),仍會產(chǎn)生缺頁中斷姐军,這次必須分配1物理頁了铁材,進(jìn)入寫時(shí)復(fù)制的流程;
[if !supportLists]4奕锌、[endif]當(dāng)使用fork等系統(tǒng)調(diào)用創(chuàng)建子進(jìn)程時(shí)著觉,子進(jìn)程不論有無自己的vma,它的vma都有對于物理頁的映射惊暴,但它們共同映射的這些物理頁屬性為只讀饼丘,即linux并未給子進(jìn)程真正分配物理頁,當(dāng)父子進(jìn)程任何一方要寫相應(yīng)物理頁時(shí)辽话,導(dǎo)致缺頁中斷的寫時(shí)復(fù)制肄鸽。
當(dāng)進(jìn)程執(zhí)行過程中發(fā)生缺頁中斷時(shí),需要進(jìn)行頁面換入油啤,步驟如下:
<1>首先硬件會陷入內(nèi)核典徘,在堆棧中保存程序計(jì)數(shù)器。大多數(shù)機(jī)器將當(dāng)前指令的各種狀態(tài)信息保存在CPU中特殊的寄存器中益咬。
<2>啟動一個(gè)匯編代碼例程保存通用寄存器及其它易失性信息逮诲,以免被操作系統(tǒng)破壞。這個(gè)例程將操作系統(tǒng)作為一個(gè)函數(shù)來調(diào)用。
(在頁面換入換出的過程中可能會發(fā)生上下文換行汛骂,導(dǎo)致破壞當(dāng)前程序計(jì)數(shù)器及通用寄存器中本進(jìn)程的信息)
<3>當(dāng)操作系統(tǒng)發(fā)現(xiàn)是一個(gè)頁面中斷時(shí)罕模,查找出來發(fā)生頁面中斷的虛擬頁面(進(jìn)程地址空間中的頁面)。這個(gè)虛擬頁面的信息通常會保存在一個(gè)硬件寄存器中帘瞭,如果沒有的話淑掌,操作系統(tǒng)必須檢索程序計(jì)數(shù)器,取出這條指令蝶念,用軟件分析該指令抛腕,通過分析找出發(fā)生頁面中斷的虛擬頁面。
<4>檢查虛擬地址的有效性及安全保護(hù)位媒殉。如果發(fā)生保護(hù)錯(cuò)誤担敌,則殺死該進(jìn)程。
<5>操作系統(tǒng)查找一個(gè)空閑的頁框(物理內(nèi)存中的頁面)廷蓉,如果沒有空閑頁框則需要通過頁面置換算法找到一個(gè)需要換出的頁框全封。
<6>如果找的頁框中的內(nèi)容被修改了,則需要將修改的內(nèi)容保存到磁盤上桃犬,此時(shí)會引起一個(gè)寫磁盤調(diào)用刹悴,發(fā)生上下文切換(在等待磁盤寫的過程中讓其它進(jìn)程運(yùn)行)。
(注:此時(shí)需要將頁框置為忙狀態(tài)攒暇,以防頁框被其它進(jìn)程搶占掉)
<7>頁框干凈后土匀,操作系統(tǒng)根據(jù)虛擬地址對應(yīng)磁盤上的位置,將保持在磁盤上的頁面內(nèi)容復(fù)制到“干凈”的頁框中形用,此時(shí)會引起一個(gè)讀磁盤調(diào)用就轧,發(fā)生上下文切換。
<8>當(dāng)磁盤中的頁面內(nèi)容全部裝入頁框后田度,向操作系統(tǒng)發(fā)送一個(gè)中斷妒御。操作系統(tǒng)更新內(nèi)存中的頁表項(xiàng),將虛擬頁面映射的頁框號更新為寫入的頁框镇饺,并將頁框標(biāo)記為正常狀態(tài)携丁。
<9>恢復(fù)缺頁中斷發(fā)生前的狀態(tài),將程序指令器重新指向引起缺頁中斷的指令兰怠。
<10>調(diào)度引起頁面中斷的進(jìn)程,操作系統(tǒng)返回匯編代碼例程李茫。
<11>匯編代碼例程恢復(fù)現(xiàn)場揭保,將之前保存在通用寄存器中的信息恢復(fù)
(以下格式自行編排,編輯時(shí)刪除)
Printf會調(diào)用malloc魄宏,請簡述動態(tài)內(nèi)存管理的基本方法與策略秸侣。
1)首次適應(yīng):首次適應(yīng)策略要求空閑區(qū)按其起始地址從小到大排列,當(dāng)某一用戶作業(yè)要求裝入內(nèi)存時(shí),存儲分配程序從起始地址最小的空間區(qū)開始掃描味榛,直到找到滿足該作業(yè)要求的空閑區(qū)為止椭坚。
2)循環(huán)首次適應(yīng):在查找空閑區(qū)時(shí),不再每次從鏈?zhǔn)组_始查找搏色,而是從上一次找到的空閑區(qū)的下一個(gè)空閑區(qū)開始查找善茎,直到找到一個(gè)能滿足要求的空閑區(qū)為止,并從中劃出一塊與請求大小相等的內(nèi)存空間分給該作業(yè)频轿。
3)最佳適應(yīng):該策略總是把滿足要求垂涯,又使最小的空閑區(qū)分配給請求作業(yè),即在空閑區(qū)表中航邢,按空閑區(qū)的大小從小到大排列耕赘,建立索引,當(dāng)用戶作業(yè)請求內(nèi)存空間時(shí)膳殷,從索引表中找到第一個(gè)滿足該作業(yè)的空閑區(qū)分給它操骡。
4)最差適應(yīng):該策略總是把最大的空閑區(qū)分配給請求作業(yè),空閑區(qū)表(空閑區(qū)鏈)中的空閑分區(qū)要按大小從大到小進(jìn)行排序赚窃,自表頭開始查找到第一個(gè)滿足要求的空閑分區(qū)分配給作業(yè)册招。
本小節(jié)主要介紹了hello在執(zhí)行時(shí),有關(guān)儲存的管理的各項(xiàng)相關(guān)內(nèi)容考榨。
?
(第7章 2分)
設(shè)備的模型化:文件
設(shè)備管理:unix io接口
Unix IO接口是連接CPU與外設(shè)之間的部件跨细,它完成CPU與外界的信息傳送。還包括輔助CPU工作的外圍電路河质,如中斷控制器冀惭、DMA控制器、定時(shí)器掀鹅、高速CACHE散休。
它最重要的四個(gè)函數(shù),打開open乐尊,關(guān)閉close戚丸,讀取read,寫入write
從vsprintf生成顯示信息扔嵌,到write系統(tǒng)函數(shù)限府,到陷阱-系統(tǒng)調(diào)用 int 0x80或syscall.
字符顯示驅(qū)動子程序:從ASCII到字模庫到顯示vram(存儲每一個(gè)點(diǎn)的RGB顏色信息)。
顯示芯片按照刷新頻率逐行讀取vram痢缎,并通過信號線向液晶顯示器傳輸每一個(gè)點(diǎn)(RGB分量)胁勺。
異步異常-鍵盤中斷的處理:鍵盤中斷處理子程序。接受按鍵掃描碼轉(zhuǎn)成ascii碼独旷,保存到系統(tǒng)的鍵盤緩沖區(qū)署穗。
getchar等調(diào)用read系統(tǒng)函數(shù)寥裂,通過系統(tǒng)調(diào)用讀取按鍵ascii碼,直到接受到回車鍵才返回案疲。
本小節(jié)介紹了Linux的IO設(shè)備封恰,接口和接口函數(shù),以及prinf和getchar實(shí)現(xiàn)過程
(第8章1分)
Hello.c從被編寫出來到執(zhí)行褐啡,經(jīng)歷了下面的這些流程:
[if !supportLists](1)?[endif]預(yù)處理器將hello.c預(yù)處理成為hello.i?
[if !supportLists](2)?[endif]編譯器將hello.i翻譯成匯編語言hello.s
[if !supportLists](3)?[endif]匯編器將hello.s匯編成可重定位二進(jìn)制代碼hello.o
[if !supportLists](4)?[endif]鏈接器將外部文件和hello.o鏈接成為可執(zhí)行二進(jìn)制文件hello
[if !supportLists](5)?[endif]shell進(jìn)程調(diào)用fork為其創(chuàng)建子進(jìn)程.
[if !supportLists](6)?[endif]shell調(diào)用execve函數(shù)使得hello的數(shù)據(jù)寫入子進(jìn)程的虛擬內(nèi)存空間诺舔,從而使得hello的代碼可以在一個(gè)可執(zhí)行文件中被執(zhí)行。
如今的電腦程序運(yùn)行速度主要受限制于讀取的速度春贸,未來如果能夠?qū)崿F(xiàn)cache的更準(zhǔn)確命中或者提高cache每一級的容量混萝,可以更好的提升電腦速度。
(結(jié)論0分萍恕,缺失 -1分逸嘀,根據(jù)內(nèi)容酌情加分)
hello.i預(yù)處理之后文本文件
hello.s編譯之后的匯編文件
hello.o匯編之后的可重定位目標(biāo)執(zhí)行
Hello鏈接之后的可執(zhí)行目標(biāo)文件
(附件0分,缺失 -1分)
為完成本次大作業(yè)你翻閱的書籍與網(wǎng)站等
[1]林來興.?空間控制技術(shù)[M].?北京:中國宇航出版社允粤,1992:25-42.
[2] ?辛希孟.?信息技術(shù)與信息服務(wù)國際研討會論文集:A集[C].?北京:中國科學(xué)出版社崭倘,1999.
[3]趙耀東. 新時(shí)代的工業(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.
(參考文獻(xiàn)0分,缺失 -1分)
`???k?x?κ?