哈工大计算机系统2022春 大作业 程序人生
計(jì)算機(jī)系統(tǒng)
計(jì)算機(jī)系統(tǒng)
大作業(yè)
題 ????目 ?程序人生-Hello’s P2P?
專?????? 業(yè) ????????計(jì)算機(jī)科學(xué)與技術(shù)??????????????
學(xué) ?? 號(hào) ? ? ? ? ? ? ? ? ? ? ??
班 ?? 級(jí) ? ? ? ? ? ? ? ? ? ? ??
學(xué)?????? 生 ?????????????
指 導(dǎo) 教 師 ????????????????劉宏偉???
計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院
2021年5月
摘? 要
本文對(duì)hello程序的整個(gè)生命周期進(jìn)行了的分析,包括 hello.c源程序的編寫(xiě),預(yù)處理生成hello.i文件,翻譯生成匯編語(yǔ)言文件hello.s,以及可重定位目標(biāo)文件hello.o,最后將hello.o和系統(tǒng)目標(biāo)文件鏈接起來(lái),創(chuàng)建了一個(gè)可執(zhí)行目標(biāo)文件hello。調(diào)用fork函數(shù)創(chuàng)建進(jìn)程,execve加載hello進(jìn)入內(nèi)存,控制程序邏輯流的運(yùn)行,中斷,上下文切換和異常的處理,最后結(jié)束進(jìn)程并由父進(jìn)程進(jìn)行回收
目? 錄
第1章 概述................................................................................................................ - 4 -
1.1 Hello簡(jiǎn)介......................................................................................................... - 4 -
1.2 環(huán)境與工具........................................................................................................ - 4 -
1.3 中間結(jié)果............................................................................................................ - 4 -
1.4 本章小結(jié)............................................................................................................ - 4 -
第2章 預(yù)處理............................................................................................................ - 5 -
2.1 預(yù)處理的概念與作用........................................................................................ - 5 -
2.2在Ubuntu下預(yù)處理的命令............................................................................. - 5 -
2.3 Hello的預(yù)處理結(jié)果解析................................................................................. - 5 -
2.4 本章小結(jié)............................................................................................................ - 5 -
第3章 編譯................................................................................................................ - 6 -
3.1 編譯的概念與作用............................................................................................ - 6 -
3.2 在Ubuntu下編譯的命令................................................................................ - 6 -
3.3 Hello的編譯結(jié)果解析..................................................................................... - 6 -
3.4 本章小結(jié)............................................................................................................ - 6 -
第4章 匯編................................................................................................................ - 7 -
4.1 匯編的概念與作用............................................................................................ - 7 -
4.2 在Ubuntu下匯編的命令................................................................................ - 7 -
4.3 可重定位目標(biāo)elf格式.................................................................................... - 7 -
4.4 Hello.o的結(jié)果解析.......................................................................................... - 7 -
4.5 本章小結(jié)............................................................................................................ - 7 -
第5章 鏈接................................................................................................................ - 8 -
5.1 鏈接的概念與作用............................................................................................ - 8 -
5.2 在Ubuntu下鏈接的命令................................................................................ - 8 -
5.3 可執(zhí)行目標(biāo)文件hello的格式........................................................................ - 8 -
5.4 hello的虛擬地址空間..................................................................................... - 8 -
5.5 鏈接的重定位過(guò)程分析.................................................................................... - 8 -
5.6 hello的執(zhí)行流程............................................................................................. - 8 -
5.7 Hello的動(dòng)態(tài)鏈接分析..................................................................................... - 8 -
5.8 本章小結(jié)............................................................................................................ - 9 -
第6章 hello進(jìn)程管理....................................................................................... - 10 -
6.1 進(jìn)程的概念與作用.......................................................................................... - 10 -
6.2 簡(jiǎn)述殼Shell-bash的作用與處理流程........................................................ - 10 -
6.3 Hello的fork進(jìn)程創(chuàng)建過(guò)程......................................................................... - 10 -
6.4 Hello的execve過(guò)程..................................................................................... - 10 -
6.5 Hello的進(jìn)程執(zhí)行........................................................................................... - 10 -
6.6 hello的異常與信號(hào)處理............................................................................... - 10 -
6.7本章小結(jié).......................................................................................................... - 10 -
第7章 hello的存儲(chǔ)管理................................................................................... - 11 -
7.1 hello的存儲(chǔ)器地址空間................................................................................ - 11 -
7.2 Intel邏輯地址到線性地址的變換-段式管理............................................... - 11 -
7.3 Hello的線性地址到物理地址的變換-頁(yè)式管理.......................................... - 11 -
7.4 TLB與四級(jí)頁(yè)表支持下的VA到PA的變換................................................ - 11 -
7.5 三級(jí)Cache支持下的物理內(nèi)存訪問(wèn)............................................................. - 11 -
7.6 hello進(jìn)程fork時(shí)的內(nèi)存映射..................................................................... - 11 -
7.7 hello進(jìn)程execve時(shí)的內(nèi)存映射................................................................. - 11 -
7.8 缺頁(yè)故障與缺頁(yè)中斷處理.............................................................................. - 11 -
7.9動(dòng)態(tài)存儲(chǔ)分配管理........................................................................................... - 11 -
7.10本章小結(jié)........................................................................................................ - 12 -
第8章 hello的IO管理.................................................................................... - 13 -
8.1 Linux的IO設(shè)備管理方法............................................................................. - 13 -
8.2 簡(jiǎn)述Unix IO接口及其函數(shù).......................................................................... - 13 -
8.3 printf的實(shí)現(xiàn)分析........................................................................................... - 13 -
8.4 getchar的實(shí)現(xiàn)分析....................................................................................... - 13 -
8.5本章小結(jié).......................................................................................................... - 13 -
結(jié)論............................................................................................................................ - 14 -
附件............................................................................................................................ - 15 -
參考文獻(xiàn).................................................................................................................... - 16 -
第1章 概述
1.1 Hello簡(jiǎn)介
?1. 編寫(xiě)hello.c程序,得到源程序
?2. hello.c通過(guò)gcc編譯器處理得到可執(zhí)行文件hello,實(shí)際過(guò)程為
?? ?2.1 ?hello.c經(jīng)過(guò)預(yù)處理修改源程序代碼生成hello.i文本文件,這是一個(gè)新的c程序
?? ?2.2? hello.i再經(jīng)過(guò)編譯生成匯編程序hello.s
?? ?2.3? hello.s通過(guò)匯編指令集變成二進(jìn)制可重定位目標(biāo)文件hello.o但此時(shí)該文件還不可以執(zhí)行
?? ?2.4? 最后經(jīng)過(guò)鏈接,將hello.o文件與一些提前編譯好的文件合并生成hello可執(zhí)行文件
?3. hello文件存入磁盤(pán),等待調(diào)用
?4.通過(guò)命令解釋程序shell為hello創(chuàng)建新的進(jìn)程,在通過(guò)調(diào)用execve對(duì)虛擬內(nèi)存進(jìn)行映射,通過(guò)mmap為hello開(kāi)辟一片空間。
?5.最后中央處理器CPU從虛擬內(nèi)存中截取代碼和數(shù)據(jù),調(diào)度器為進(jìn)程規(guī)劃時(shí)間片,在發(fā)生異常時(shí)觸發(fā)異常處理子程序
1.2環(huán)境與工具
??
1.硬件環(huán)境:Intel(R) Core(TM) i7-10875H CPU 2.30 GHz;16GRAM;1024Disk
2.軟件環(huán)境:Windows11 64位; Ubuntu 20.04 LTS 64位
3.工具:codeblocks;gdb;
1.3 中間結(jié)果
? 1.hello.c 程序的源文件,用于編寫(xiě)代碼
??2.hello.s 編譯后的文件
??3.hello.o 匯編后的文件,用于查看反匯編后的代碼
??4.hello.i 預(yù)處理后的文件,可以對(duì)比查看預(yù)處理的內(nèi)容
??5.hello.elf ?hello.o的elf格式文件
??6.hello.txt ?hello反匯編的文件
??7.hello 最終生成的可執(zhí)行文件
8.hello1.elf ?hello的elf格式文件
1.4 本章小結(jié)
本章主要介紹了hello程序的編譯執(zhí)行大概過(guò)程,說(shuō)明了軟件運(yùn)行的設(shè)備環(huán)境和硬件設(shè)施。
(第1章0.5分)
第2章 預(yù)處理
2.1 預(yù)處理的概念與作用
1.概念:根據(jù)以#開(kāi)頭的代碼,修改源程序
2.作用:讀取指定文件的內(nèi)容并插入源程序,得到一個(gè)新的c程序。
2.2在Ubuntu下預(yù)處理的命令
命令:gcc -E -o hello.i hello.c
2.3 Hello的預(yù)處理結(jié)果解析
hello.i文件部分內(nèi)容如圖所示:
目測(cè)文件內(nèi)容依舊是可閱讀的c語(yǔ)言程序代碼,但是對(duì)一些函數(shù)等內(nèi)容進(jìn)行了替換。可以得出預(yù)處理的內(nèi)容是對(duì)源程序進(jìn)行的展開(kāi)。
2.4 本章小結(jié)
本章了解了對(duì)hello文件的預(yù)處理的具體過(guò)程和結(jié)果,通過(guò)對(duì)比hello.i和hello文件可以看出預(yù)處理的本質(zhì)工作是進(jìn)行c語(yǔ)言代碼的補(bǔ)充和替換。
(第2章0.5分)
第3章 編譯
3.1 編譯的概念與作用
概念:將文本文件hello.i轉(zhuǎn)化為文件hello.s
作用:進(jìn)行詞法分析和語(yǔ)法分析,判斷是否存在語(yǔ)法詞法錯(cuò)誤
3.2 在Ubuntu下編譯的命令
命令:gcc -S hello.i -o hello.s
3.3 Hello的編譯結(jié)果解析
hello.s文件部分內(nèi)容如下:
.file “hello.c”????? 聲明源文件
.text?????? ???????????代碼段,存放函數(shù)的二進(jìn)制指令
.section ?.rofata????? 只讀數(shù)據(jù)段,存放“”中的字符串?????
.string “hello %s %s\n” 聲明一段字符
.globl? main?????????? 聲明全局變量?? ???????????
.type? main,@function ?聲明符號(hào)類型(函數(shù)還是數(shù)據(jù))
.align 8?????????????? ?聲明存放地址對(duì)齊的方式
hello程序中聲明了兩個(gè)字符串,都保存在只讀數(shù)據(jù)段中
hello程序中也聲明了一個(gè)局部變量i,暫時(shí)保存在堆棧 -4(%rbp)的位置
hello程序的參數(shù)argc也保存在堆棧中
hello程序中還存在著一個(gè)數(shù)組argv[]作為函數(shù)的參數(shù),存放在 -32(%rbp)的位置
匯編代碼中立即數(shù)直接在代碼中表示
賦值操作:mov a? b? 代碼表示將a中的數(shù)據(jù)復(fù)制到b中,從而實(shí)現(xiàn)賦值操作, mov代碼一般會(huì)帶后綴表示操作的數(shù)據(jù)大小
運(yùn)算操作:add ?a? b? 代碼表示將a加給b,可以實(shí)現(xiàn)加法運(yùn)算,hello程序中主要的運(yùn)算操作為循環(huán)過(guò)程中的i++,實(shí)現(xiàn)方式如圖
循環(huán)與跳轉(zhuǎn):通過(guò)cmpl代碼對(duì)后條件碼進(jìn)行判斷,je和jle則利用條件碼進(jìn)行跳轉(zhuǎn),從而實(shí)現(xiàn)循環(huán)
函數(shù)傳參:先設(shè)定一個(gè)寄存器,將參數(shù)傳給這個(gè)設(shè)定的寄存器后
函數(shù)調(diào)用:通過(guò)call來(lái)跳轉(zhuǎn)到調(diào)用的函數(shù)開(kāi)頭的地址。
3.4 本章小結(jié)
本章主要從c語(yǔ)言的數(shù)據(jù),賦值語(yǔ)句,算術(shù)操作,邏輯/位操作,跳轉(zhuǎn)操作,函數(shù)操作這幾點(diǎn)入手,分析了編譯器是如何把hello.i文件從高級(jí)的c語(yǔ)言變成了低階的匯編語(yǔ)言
第4章 匯編
4.1 匯編的概念與作用
??? 概念:通過(guò)指令集將匯編程序hello.s轉(zhuǎn)化為機(jī)器指令并按一定規(guī)則打包得到可重定位目標(biāo)文件hello.o
作用:將匯編語(yǔ)言翻譯成機(jī)器語(yǔ)言,使其在鏈接時(shí)能被找到,鏈接后能夠被機(jī)器識(shí)別并執(zhí)行。
4.2 在Ubuntu下匯編的命令
命令:gcc -c -o hello.o hello.s
4.3 可重定位目標(biāo)elf格式
hello.elf文件的部分內(nèi)容如下:
分析內(nèi)容:
4.4 Hello.o的結(jié)果解析
通過(guò)objdump -d -r hello.o命令可以得到hello.o文件的反匯編代碼
內(nèi)容如下:
與前面hello.s文件進(jìn)行對(duì)比:
Hello.o的反匯編代碼中,je后的代碼不再是原來(lái)的段名,改成了確定的地址,這是因?yàn)槎伪旧碇皇菂R編語(yǔ)言中用于幫助編寫(xiě)的記憶符號(hào),匯編成機(jī)器語(yǔ)言后不能繼續(xù)使用
2.函數(shù)調(diào)用代碼不同:
Call指令后不再接函數(shù)的名字,而是一條重定位條目指引的信息
立即數(shù)都變成了十六進(jìn)制,較于十進(jìn)制更容易處理
4.5 本章小結(jié)
本章主要介紹了匯編過(guò)程,我們通過(guò)查看hello.elf文件內(nèi)容了解了可重定位目標(biāo)文件的格式,反匯編得到了hello.o文件的匯編代碼并與hello.i進(jìn)行了對(duì)比,了解了匯編語(yǔ)言轉(zhuǎn)化為機(jī)器語(yǔ)言的過(guò)程。
第5章 鏈接
5.1 鏈接的概念與作用
1.概念:鏈接是將各種代碼和數(shù)據(jù)片段收集并組合成為一個(gè)單一文件的過(guò)程,這個(gè)文件可以被加載到內(nèi)存并執(zhí)行
2.作用:允許我們把程序分解為更小,更好管理的模塊,可以獨(dú)立的修改和編譯這些模塊,不必重新編譯整個(gè)程序。
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.3 可執(zhí)行目標(biāo)文件hello的格式
通過(guò)readelf -a hello>hello1.elf命令可以生成hello1.elf文件,文件部分內(nèi)容如下圖:
1.hello是一個(gè)可執(zhí)行目標(biāo)文件,有27個(gè)節(jié)
2. 節(jié)頭對(duì) hello中所有的節(jié)信息進(jìn)行了聲明,包括大小和偏移量
3.重定位節(jié):
4.符號(hào)表:
5.4 hello的虛擬地址空間
分析程序頭LOAD可加載的程序段的地址為0x400000
使用edb加載程序,查看程序信息:
在0x400000~0x401000段中,程序被載入,虛擬地址0x400000開(kāi)始,到0x400fff結(jié)束,可以通過(guò)edb找到各個(gè)節(jié)的信息,虛擬地址開(kāi)始于0x4010f0,大小為0x145
5.5 鏈接的重定位過(guò)程分析
命令:objdump -d -r hello > hello.txt
生成的文件部分內(nèi)容如下:
hello的重定位過(guò)程:
?? 1.重定位節(jié)和符號(hào)定義鏈接器將所有類型相同的節(jié)合并在一起后,這個(gè)節(jié)就作為可執(zhí)行目標(biāo)文件的節(jié)。然后鏈接器把運(yùn)行時(shí)的內(nèi)存地址賦給新的聚合節(jié),賦給輸入模塊定義的每個(gè)節(jié),以及賦給輸入模塊定義的每個(gè)符號(hào),當(dāng)這一步完成時(shí),程序中每條指令和全局變量都有唯一運(yùn)行時(shí)的地址。
?? 2.重定位節(jié)中的符號(hào)引用這一步中,連接器修改代碼節(jié)和數(shù)據(jù)節(jié)中對(duì)每個(gè)符號(hào)的引用,使他們指向正確的運(yùn)行時(shí)地址。
?? 3.重定位條目當(dāng)編譯器遇到對(duì)最終位置未知的目標(biāo)引用時(shí),它會(huì)生成一個(gè)重定位條目。代碼的重定位條目放在.rel.txt中。
5.6 hello的執(zhí)行流程
通過(guò)edb打開(kāi)hello文件,運(yùn)用step into指令調(diào)試,遇到函數(shù)會(huì)發(fā)生跳轉(zhuǎn)
程序地址
??????? 00007f3cda2f9df0
??????? 00007f264db03df0
??????? 00007f035f63f7d0
??????? 0000400550
??????? 000007fd34770bb10
??????? 000007f03a4843b27
??????? 00000400610
??????? 00000400582
??????? 00000400530
?
5.7 Hello的動(dòng)態(tài)鏈接分析
5.8 本章小結(jié)
本章研究了鏈接的過(guò)程。通過(guò)edb查看hello的虛擬地址空間,對(duì)比hello與hello.o的反匯編代碼
第6章 hello進(jìn)程管理
6.1 進(jìn)程的概念與作用
1.概念:進(jìn)程(Process)是計(jì)算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ)。
2.作用:進(jìn)程作為一個(gè)執(zhí)行中程序的實(shí)例,系統(tǒng)中每個(gè)程序都運(yùn)行在某個(gè)進(jìn)程的上下文中。
6.2 簡(jiǎn)述殼Shell-bash的作用與處理流程
1.shell程序的作用:Linux系統(tǒng)中,Shell是一個(gè)命令解釋程序,它為用戶提供操作命令和文件的界面,用戶可以直接通過(guò)在shell程序上輸入的指令調(diào)用相應(yīng)的程序
2.流程:
a.在shell命令行中輸入命令:$./hello,解釋器構(gòu)造argv和envp;
b. 調(diào)用fork()函數(shù)創(chuàng)建子進(jìn)程,
c. 調(diào)用execve()函數(shù)在當(dāng)前進(jìn)程(新創(chuàng)建的子進(jìn)程)的上下文中加載并運(yùn)行hello
程序。將hello中的.text節(jié)、.data節(jié)、.bss節(jié)等內(nèi)容加載到當(dāng)前進(jìn)程的虛擬地址空
間
d. 調(diào)用hello程序的main()函數(shù),hello程序開(kāi)始在一個(gè)進(jìn)程的上下文中運(yùn)行。
6.3 Hello的fork進(jìn)程創(chuàng)建過(guò)程
在終端中輸入./hello 學(xué)號(hào) 姓名 1命令后,shell會(huì)處理該命令,判斷出不是內(nèi)置命令,則會(huì)調(diào)用fork函數(shù)創(chuàng)建一個(gè)新的子進(jìn)程,子進(jìn)程幾乎但不完全與父進(jìn)程相同。通過(guò)fork函數(shù),子進(jìn)程得到與父進(jìn)程用戶級(jí)虛擬地址空間相同的但是虛擬地址獨(dú)立、PID也不相同的一份副本。
6.4 Hello的execve過(guò)程
創(chuàng)建了一個(gè)子進(jìn)程時(shí),子進(jìn)程調(diào)用exceve函數(shù)在當(dāng)前子進(jìn)程的上下文加載并運(yùn)行一個(gè)新的程序,會(huì)經(jīng)過(guò)以下步驟:
1.刪除之前進(jìn)程在用戶部分中已存在的結(jié)構(gòu)。
2.創(chuàng)建新的代碼、數(shù)據(jù)、堆和棧段。
3.映射共享區(qū)域。先動(dòng)態(tài)鏈接共享對(duì)象,然后再映射到用戶虛擬地址空間中的共享區(qū)域。
4.設(shè)置程序計(jì)數(shù)器(PC)。Exceve會(huì)設(shè)置當(dāng)前進(jìn)程的上下文中的程序計(jì)數(shù)器,使之指向代碼區(qū)域的入口點(diǎn)。
6.5 Hello的進(jìn)程執(zhí)行
1.進(jìn)程上下文切換:如果系統(tǒng)調(diào)用因?yàn)榈却硞€(gè)事件發(fā)生而阻塞,那么內(nèi)核可以讓當(dāng)前進(jìn)程休眠,切換到另一個(gè)進(jìn)程
2.進(jìn)程時(shí)間片:進(jìn)程的運(yùn)行本質(zhì)上是CPU不斷從程序計(jì)數(shù)器 PC 指示的地址處取出指令并執(zhí)行,值的序列叫做邏輯控制流。在一個(gè)程序被調(diào)運(yùn)行開(kāi)始到被另一個(gè)進(jìn)程打斷,中間的時(shí)間就是運(yùn)行的時(shí)間片
3.用戶態(tài)和核心態(tài): 進(jìn)程只有故障、中斷或陷入系統(tǒng)調(diào)用時(shí)才會(huì)得到內(nèi)核訪問(wèn)權(quán)限,其他情況下始終處于用戶權(quán)限之中,這樣可以保證系統(tǒng)的安全性。
4.進(jìn)程調(diào)度:即加載保存的寄存器,切換虛擬地址空間
6.6 hello的異常與信號(hào)處理
1.正常運(yùn)行:
2.CTRL+Z: 輸入ctrl-z默認(rèn)結(jié)果是掛起前臺(tái)的作業(yè),hello進(jìn)程并沒(méi)有回收,而是運(yùn)行在后臺(tái)下,用ps命令可以看到,hello進(jìn)程并沒(méi)有被回收。
3.CTRL+C:
內(nèi)核發(fā)送一個(gè)SIGINT信號(hào)到前臺(tái)進(jìn)程組的每個(gè)進(jìn)程,默認(rèn)情況是終止前臺(tái)作業(yè),用ps查看前臺(tái)進(jìn)程組發(fā)現(xiàn)沒(méi)有hello進(jìn)程,如圖所示。
6.7本章小結(jié)
本章了解了hello進(jìn)程的執(zhí)行過(guò)程。內(nèi)核為程序調(diào)度,異常處理程序處理各種異常。不同信號(hào)有不同的處理機(jī)制,不同的shell命令,hello也有不同的響應(yīng)結(jié)果。
第7章 hello的存儲(chǔ)管理
7.1 hello的存儲(chǔ)器地址空間
1.邏輯地址:程序經(jīng)過(guò)編譯后出現(xiàn)在匯編代碼中的地址。
2.線性地址:邏輯地址向物理地址轉(zhuǎn)化過(guò)程中的一步,邏輯地址經(jīng)過(guò)段機(jī)制后轉(zhuǎn)化為線性地址
3.虛擬地址:就是線性地址。
4.物理地址:CPU通過(guò)地址總線的尋址,找到真實(shí)的物理內(nèi)存對(duì)應(yīng)地址。
7.2 Intel邏輯地址到線性地址的變換-段式管理
1.原理:在段式存儲(chǔ)管理 中,將程序的地址空間劃分為若干個(gè)段(segment),為每個(gè)段分配一個(gè)連續(xù)的分區(qū),進(jìn)程中的各個(gè)段可以不連續(xù)地存放在內(nèi)存的不同分區(qū)中。程序加載時(shí),操作系統(tǒng)為 所有段分配其所需內(nèi)存,這些段不必連續(xù)。程序通過(guò)分段可以劃分為多個(gè)模塊。
2.邏輯地址的組成:一個(gè)邏輯地址由段標(biāo)識(shí)符和段內(nèi)偏移量組成。段標(biāo)識(shí)符是一個(gè)16位長(zhǎng)的字段。其中前13位是一個(gè)索引號(hào)。后面3位包含一些硬件細(xì)節(jié)。
3.查看方式:
給定一個(gè)完整的邏輯地址 段標(biāo)識(shí)符a:段內(nèi)偏移量b
看段選擇符的T1=0還是1,了解當(dāng)前要轉(zhuǎn)換是全局段描述符表中的段還是局部段描述符表中的段。
根據(jù)段選擇符的前13位查找到對(duì)應(yīng)的段描述符,確定Base基地址。
將Base+offset,就是線性地址
7.3 Hello的線性地址到物理地址的變換-頁(yè)式管理
1.基本原理:將 程序的邏輯地址空間劃分為固定大小的頁(yè),而物理內(nèi)存劃分為同樣大小的頁(yè)框。程序加載時(shí),可將任意一頁(yè)放人內(nèi)存中任意一個(gè)頁(yè)框,這些頁(yè)框不必連續(xù),從而實(shí)現(xiàn)了離散分配。
2. 傳輸單元:系統(tǒng)將虛擬頁(yè)作為進(jìn)行數(shù)據(jù)傳輸?shù)膯卧inux下每個(gè)虛擬頁(yè)大小為4KB。物理內(nèi)存也被分割為物理頁(yè), MMU(內(nèi)存管理單元)負(fù)責(zé)地址翻譯,MMU使用頁(yè)表將虛擬頁(yè)到物理頁(yè)的映射,即虛擬地址到物理地址的映射。
3. n位的虛擬地址包含兩個(gè)部分:一個(gè)p位的虛擬頁(yè)面偏移(VPO),一個(gè)n-p位的虛擬頁(yè)號(hào)(VPN),MMU利用VPN選擇適當(dāng)?shù)腜TE,根據(jù)PTE,我們知道虛擬頁(yè)的信息,如果虛擬頁(yè)是已緩存的,那直接將頁(yè)表?xiàng)l目的物理頁(yè)號(hào)和虛擬地址的VPO串聯(lián)起來(lái)就得到一個(gè)相應(yīng)的物理地址。VPO和PPO是相同的。如果虛擬頁(yè)是未緩存的,會(huì)觸發(fā)一個(gè)缺頁(yè)故障。調(diào)用一個(gè)缺頁(yè)處理子程序?qū)⒋疟P(pán)的虛擬頁(yè)重新加載到內(nèi)存中,然后再執(zhí)行這個(gè)導(dǎo)致缺頁(yè)的指令。
7.4 TLB與四級(jí)頁(yè)表支持下的VA到PA的變換
1.TLB:當(dāng)處理 器要在主內(nèi)存尋址時(shí),不是直接在內(nèi)存的物理地址里查找的,而是通過(guò)一組虛擬地址轉(zhuǎn)換到主內(nèi)存的物理地址,TLB就是負(fù)責(zé)將虛擬內(nèi)存地址翻譯成實(shí)際的物理內(nèi) 存地址,而CPU尋址時(shí)會(huì)優(yōu)先在TLB中進(jìn)行尋址。
2:VA->PA:處理器生成一個(gè)虛擬地址,并將其傳送給MMU。MMU用VPN向TLB請(qǐng)求對(duì)應(yīng)的PTE,命中得到PA。否則MMU查詢頁(yè)表,CR3確定第一級(jí)頁(yè)表的起始地址,VPN1確定在第一級(jí)頁(yè)表中的偏移量,查詢出PTE,最終在第四級(jí)頁(yè)表中找到PPN,與VPO組合成物理地址PA,添加到PLT。
7.5 三級(jí)Cache支持下的物理內(nèi)存訪問(wèn)
獲得物理地址之后,先取出組索引對(duì)應(yīng)位,在L1中尋找對(duì)應(yīng)組。如果存在,則比較標(biāo)志位,相等后檢查有效位是否為1.如果都滿足則命中取出值傳給CPU,否則按順序?qū)2cache、L3cache、內(nèi)存進(jìn)行相同操作,直到出現(xiàn)命中。然后再一級(jí)一級(jí)向上傳,如果有空閑塊則將目標(biāo)塊放置到空閑塊中,否則將緩存中的某個(gè)塊驅(qū)逐,將目標(biāo)塊放到被驅(qū)逐塊的位置。
7.6 hello進(jìn)程fork時(shí)的內(nèi)存映射
當(dāng)fork 函數(shù)被 shell 進(jìn)程調(diào)用時(shí),內(nèi)核創(chuàng)建子進(jìn)程并分配給它一個(gè)唯一的 PID,同時(shí)創(chuàng)建了當(dāng)前進(jìn)程的mm_struct、區(qū)域結(jié)構(gòu)和頁(yè)表的原樣副本。它將這兩個(gè)進(jìn)程的每個(gè)頁(yè)面都標(biāo)記為只讀,并將兩個(gè)進(jìn)程中的每個(gè)區(qū)域結(jié)構(gòu)都標(biāo)記為私有的寫(xiě)時(shí)復(fù)制。當(dāng)fork在新進(jìn)程中返回時(shí),新進(jìn)程現(xiàn)在的虛擬內(nèi)存剛好和調(diào)用fork時(shí)存在的虛擬內(nèi)存相同。當(dāng)這兩個(gè)進(jìn)程中的任一個(gè)后來(lái)進(jìn)行寫(xiě)操作時(shí),寫(xiě)時(shí)復(fù)制機(jī)制就會(huì)創(chuàng)建新頁(yè)面。
7.7 hello進(jìn)程execve時(shí)的內(nèi)存映射
execve 函數(shù)調(diào)用加載器代碼,在當(dāng)前進(jìn)程中加載并運(yùn)行hello 需要以下幾個(gè)步驟:
1. 刪除已存在的用戶區(qū)域,刪除當(dāng)前進(jìn)程虛擬地址的用戶部分中的已存在的區(qū)域結(jié)構(gòu)。
2. 映射私有區(qū)域,為新程序的代碼、數(shù)據(jù)、 bss和棧區(qū)域創(chuàng)建新的區(qū)域結(jié)構(gòu),所有這些新的區(qū)域都是私有的、寫(xiě)時(shí)復(fù)制的。
3.共享對(duì)象由動(dòng)態(tài)鏈接映射到本進(jìn)程共享區(qū)域
4.設(shè)置程序計(jì)數(shù)器使之指向代碼區(qū)域的入口點(diǎn)
7.8 缺頁(yè)故障與缺頁(yè)中斷處理
缺頁(yè)故障:當(dāng)指令引用一個(gè)虛擬地址,在 MMU中查找頁(yè)表時(shí)發(fā)現(xiàn)與該地址相對(duì)應(yīng)的物理地址不在內(nèi)存中,因此必須從磁盤(pán)中取出的時(shí)候就會(huì)發(fā)生故障。
缺頁(yè)中斷處理:先檢查虛擬地址是否合法,再檢查進(jìn)程是否有讀、寫(xiě)或執(zhí)行該區(qū)域頁(yè)面的權(quán)限。如果兩者皆無(wú)誤,選擇一個(gè)犧牲頁(yè)面,如果這個(gè)犧牲頁(yè)面被修改過(guò),那么就將它交換出去,換入新的頁(yè)面并更新頁(yè)表。再將控制轉(zhuǎn)移給hello進(jìn)程,再次執(zhí)行觸發(fā)缺頁(yè)故障的指令
7.9動(dòng)態(tài)存儲(chǔ)分配管理
程序運(yùn)行時(shí)使用動(dòng)態(tài)內(nèi)存分配器獲得虛擬內(nèi)存。動(dòng)態(tài)內(nèi)存分配器維護(hù)著一個(gè)進(jìn)程的虛擬內(nèi)存區(qū)域,稱為堆。
對(duì)于每個(gè)進(jìn)程,內(nèi)核維護(hù)著一個(gè)變量 brk,它指向堆的頂部。分配器將堆視為一組不同大小的塊的結(jié)合來(lái)維護(hù)。每個(gè)塊就是一個(gè)連續(xù)的擬內(nèi)存片,要么是已分配的,要么是空閑的。已分配的塊顯式地保留為供應(yīng)用程序使用。空閑塊可用來(lái)分配。一個(gè)已分配的塊保持已分配狀態(tài),直到它被釋放,這種釋放要么是應(yīng)用程序顯式執(zhí)行的,要么是內(nèi)存分配器自身隱式執(zhí)行的。分配器有兩種基本風(fēng)格,兩種風(fēng)格都要求應(yīng)用顯式地分配塊,不同在于由哪個(gè)實(shí)體來(lái)負(fù)責(zé)釋放。
顯式分配器:要求應(yīng)用顯式地釋放任何已分配的塊。
隱式分配器:要求分配器檢測(cè)一個(gè)已分配塊何時(shí)不再使用,那么就釋放這個(gè)塊,垃圾收集:自動(dòng)釋放未使用的已經(jīng)分配的塊的過(guò)程。
隱式空閑鏈表:空閑塊通過(guò)頭部中的大小字段隱含地連接著。分配器可以通過(guò)遍歷堆中所有的塊,從而間接地遍歷整個(gè)空閑塊的集合。
顯式空閑鏈表:每個(gè)空閑塊中,都包含一個(gè)前驅(qū)和后繼指針。使用雙向鏈表使首次適配的時(shí)間減少到空閑塊數(shù)量的線性時(shí)間。
7.10本章小結(jié)
本章介紹了存儲(chǔ)器地址空間、段式管理、頁(yè)式管理,VA 到 PA 的變換、物理內(nèi)存訪問(wèn), h內(nèi)存映射、缺頁(yè)故障與缺頁(yè)中斷處理、包括隱式空閑鏈表和顯式空閑鏈表的動(dòng)態(tài)存儲(chǔ)分配管理。
第8章 hello的IO管理
8.1 Linux的IO設(shè)備管理方法
(以下格式自行編排,編輯時(shí)刪除)
設(shè)備的模型化:文件
設(shè)備管理:unix io接口
8.2 簡(jiǎn)述Unix IO接口及其函數(shù)
(以下格式自行編排,編輯時(shí)刪除)
8.3 printf的實(shí)現(xiàn)分析
(以下格式自行編排,編輯時(shí)刪除)
[轉(zhuǎn)]printf 函數(shù)實(shí)現(xiàn)的深入剖析 - Pianistx - 博客園
從vsprintf生成顯示信息,到write系統(tǒng)函數(shù),到陷阱-系統(tǒng)調(diào)用 int 0x80或syscall等.
字符顯示驅(qū)動(dòng)子程序:從ASCII到字模庫(kù)到顯示vram(存儲(chǔ)每一個(gè)點(diǎn)的RGB顏色信息)。
顯示芯片按照刷新頻率逐行讀取vram,并通過(guò)信號(hào)線向液晶顯示器傳輸每一個(gè)點(diǎn)(RGB分量)。
8.4 getchar的實(shí)現(xiàn)分析
(以下格式自行編排,編輯時(shí)刪除)
異步異常-鍵盤(pán)中斷的處理:鍵盤(pán)中斷處理子程序。接受按鍵掃描碼轉(zhuǎn)成ascii碼,保存到系統(tǒng)的鍵盤(pán)緩沖區(qū)。
getchar等調(diào)用read系統(tǒng)函數(shù),通過(guò)系統(tǒng)調(diào)用讀取按鍵ascii碼,直到接受到回車鍵才返回。
8.5本章小結(jié)
(以下格式自行編排,編輯時(shí)刪除)
(第8章1分)
結(jié)論
抽象對(duì)計(jì)算機(jī)系統(tǒng)是很重要的概念,底層信息用二進(jìn)制來(lái)抽象表示,進(jìn)程是對(duì)處
理器、主存和I/O設(shè)備的抽象,虛擬內(nèi)存是對(duì)主存和磁盤(pán)設(shè)備的抽象,文件是對(duì)I/O
設(shè)備的抽象,等等。
附件
1.hello.c 程序的源文件,用于編寫(xiě)代碼
2.hello.s 編譯后的文件
3.hello.o 匯編后的文件,用于查看反匯編后的代碼
4.hello.i 預(yù)處理后的文件,可以對(duì)比查看預(yù)處理的內(nèi)容
5.hello.elf? hello.o的elf格式文件
6.hello.txt? hello反匯編的文件
7.hello 最終生成的可執(zhí)行文件
8.hello1.elf? hello的elf格式文件
參考文獻(xiàn)
為完成本次大作業(yè)你翻閱的書(shū)籍與網(wǎng)站等
[1]? 深入理解計(jì)算機(jī)系統(tǒng)原書(shū)第3版-文字版.pdf
[2]? 哈爾濱工業(yè)大學(xué)計(jì)算機(jī)系統(tǒng)大作業(yè)2022春_Drama_coder的博客-CSDN博客
[3]? https://blog.csdn.net/yueyansheng2/article/details/78860040
總結(jié)
以上是生活随笔為你收集整理的哈工大计算机系统2022春 大作业 程序人生的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python语法基础14 pickle与
- 下一篇: 农林牧渔行业S2B2C系统网站提升品牌知