去皮卡多 发表于 昨天 16:27

HIT-CSAPP大作业 步伐人生-Hello‘s P2P



https://i-blog.csdnimg.cn/blog_migrate/44905a8f500cb16042e75a391a55d3c7.jpeg

盘算机系统

大作业


题     目  步伐人生-Hello’s P2P   
专       业     未来技术人工智能                  
学     号      2022110811                 
班     级      22WL023                 
学       生      李嘉莹               
指 导 教 师       刘宏伟                






盘算机科学与技术学院
2024年5月
摘  要
本论文的目标是通过跟踪hello.c文件预处理、编译、汇编、链接得到hello这个可执行目标步伐来了解hello的生命周期,进而学习一个系统。我们从他的进程的开始到回收,在存储器之间交流,见证系统整洁同等的IO管理方式。我们从Hello的一生中,见证了盘算机系统的神奇。

关键词:hello.c;预处理;编译;汇编;链接;进程管理;存储管理;I/O管理;                           

(摘要0分,缺失-1分,根据内容精彩称都酌情加分0-1分)









目  录

第1章 概述................................................... - 4 -
1.1 Hello简介............................................ - 4 -
1.2 环境与工具........................................... - 4 -
1.3 中间结果............................................... - 4 -
1.4 本章小结............................................... - 4 -
第2章 预处理............................................... - 5 -
2.1 预处理的概念与作用........................... - 5 -
2.2在Ubuntu下预处理的下令................ - 5 -
2.3 Hello的预处理结果剖析.................... - 5 -
2.4 本章小结............................................... - 5 -
第3章 编译................................................... - 6 -
3.1 编译的概念与作用............................... - 6 -
3.2 在Ubuntu下编译的下令.................... - 6 -
3.3 Hello的编译结果剖析........................ - 6 -
3.4 本章小结............................................... - 6 -
第4章 汇编................................................... - 7 -
4.1 汇编的概念与作用............................... - 7 -
4.2 在Ubuntu下汇编的下令.................... - 7 -
4.3 可重定位目标elf格式........................ - 7 -
4.4 Hello.o的结果剖析............................. - 7 -
4.5 本章小结............................................... - 7 -
第5章 链接................................................... - 8 -
5.1 链接的概念与作用............................... - 8 -
5.2 在Ubuntu下链接的下令.................... - 8 -
5.3 可执行目标文件hello的格式........... - 8 -
5.4 hello的虚拟地点空间......................... - 8 -
5.5 链接的重定位过程分析....................... - 8 -
5.6 hello的执行流程................................. - 8 -
5.7 Hello的动态链接分析........................ - 8 -
5.8 本章小结............................................... - 9 -
第6章 hello进程管理.......................... - 10 -
6.1 进程的概念与作用............................. - 10 -
6.2 简述壳Shell-bash的作用与处理流程.. - 10 -
6.3 Hello的fork进程创建过程............ - 10 -
6.4 Hello的execve过程........................ - 10 -
6.5 Hello的进程执行.............................. - 10 -
6.6 hello的异常与信号处理................... - 10 -
6.7本章小结.............................................. - 10 -
第7章 hello的存储管理...................... - 11 -
7.1 hello的存储器地点空间................... - 11 -
7.2 Intel逻辑地点到线性地点的变换-段式管理............................................................ - 11 -
7.3 Hello的线性地点到物理地点的变换-页式管理........................................................ - 11 -
7.4 TLB与四级页表支持下的VA到PA的变换................................................................ - 11 -
7.5 三级Cache支持下的物理内存访问 - 11 -
7.6 hello进程fork时的内存映射......... - 11 -
7.7 hello进程execve时的内存映射..... - 11 -
7.8 缺页故障与缺页停止处理................. - 11 -
7.9动态存储分配管理.............................. - 11 -
7.10本章小结............................................ - 12 -
第8章 hello的IO管理....................... - 13 -
8.1 Linux的IO设备管理方法................. - 13 -
8.2 简述Unix IO接口及其函数.............. - 13 -
8.3 printf的实现分析.............................. - 13 -
8.4 getchar的实现分析.......................... - 13 -
8.5本章小结.............................................. - 13 -
结论............................................................... - 14 -
附件............................................................... - 15 -
参考文献....................................................... - 16 -



第1章 概述

1.1 Hello简介

根据Hello的自白,利用盘算机系统的术语,简述Hello的P2P,020的整个过程。
P2P(Program to Process):形貌了步伐从编写到被操作系统加载并执行为进程的过程。
O2O(From Zero-0 to Zero-0):形貌了步伐从初始状态到执行任务,最后回到结束状态的完整生命周期。
1.2 环境与工具

列出你为编写本论文,折腾Hello的整个过程中,使用的软硬件环境,以及开发与调试工具。
软件环境
Windows 11 
硬件环境
Intel(R) Core(TM) i7-11370H @ 3.30GHz   3.30 GHz
RAM 16.0 GB (15.8 GB 可用)  DISK 1TB  CPU X64
开发与调试工具
GDB;EDB;gcc;CodeBlocks 64位;Visual Studio 2022 64 位;
1.3 中间结果

列出你为编写本论文,生成的中间结果文件的名字,文件的作用等。
hello.i                           处理hello.c生成的文件
hello.s                           对hello.i 进行编译生成的文件
hello.o                           对hello.s 进行汇编生成的文件
hello.elf                          对hello.o 进行readelf生成的文件
helloo                           对hello 进行objdump反汇编生成的文件
hello                            对hello.o进行链接生成的文件
hello.out.asm                     对hello进行objdump反汇编生成的文件
hello1.elf                        对hello 进行readelf生成的文件
1.4 本章小结

hello.c步伐的一生从源代码编写开始,通过编译生成可执行文件,然后在用户运行时被加载为进程,执行其逻辑,最后在完成任务退却出并由操作系统回收资源。这一生命周期体现了盘算机系统中从步伐到进程再到终止的整个过程。
(第1章0.5分)



第2章 预处理

2.1 预处理的概念与作用

概念:预处理是C和C++编译过程的第一步,它由预处理器完成,负责在编译之前对源代码进行一些基本的文本更换和宏处理。预处理器处理以#开头的预处理指令,如宏定义、文件包罗和条件编译等,使源代码在正式编译前得到简化和扩展。
作用:预处理的作用主要包括定义和更换宏、包罗头文件、条件编译、行控制和注释删除等。通过预处理,代码中的宏被更换成实际的值,必要的文件内容被插入,特定条件下的代码块被有选择地编译,从而简化代码,提高可读性和维护性,并淘汰编译错误。
2.2在Ubuntu下预处理的下令

https://i-blog.csdnimg.cn/blog_migrate/51f3db24eb72a9767d901e00cf22acab.png
图 2.0.1预处理
输入指令:gcc -E hello.c -o hello.i 生成hello.i文件
2.3 Hello的预处理结果剖析

2.3.1开始
https://i-blog.csdnimg.cn/blog_migrate/9c77726e2810e264f3974afb56dc6ca0.png
图 2.0.2基本信息
2.3.2中间主要部分
睁开的头文件 #include <stdio.h>, #include <unistd.h>, 和 #include <stdlib.h>,显示它们的内容,这些头文件会引入标准输入输出函数、系统调用函数以及通用实用函数。
https://i-blog.csdnimg.cn/blog_migrate/495e27cec782f9676beb23ba482d4f6b.png
图 2.0.3stdio.h
stdio.h 头文件主要包罗标准输入输出函数的声明。
https://i-blog.csdnimg.cn/blog_migrate/d05f5408a29f87b972566284c025fbb3.png
图 2.0.4unistd.h
unistd.h 头文件主要包罗了对POSIX操作系统 API 的访问声明。这些 API 提供对系统调用的接口,如文件操作、进程控制、环境参数等。
https://i-blog.csdnimg.cn/blog_migrate/6a868688c731e0e829914640991e141e.png
图 2.0.5stdlib.h
stdlib.h 头文件主要包罗了通用的工具函数的声明,如动态内存管理、步伐执行、整数转换、伪随机数生成等。
2.3.3末尾
与hello.c相同,没有注释
https://i-blog.csdnimg.cn/blog_migrate/53c6dcafe315cb65deaf375ba415d9a4.png
图 2.0.6主函数
2.4 本章小结

预处理器会对源代码进行一系列的文本更换和宏睁开,以生成一个扩展文件(即.i文件),这个文件包罗了全部的头文件睁开和宏更换之后的代码。预处理之后的.i文件中每段语句的功能和在原始源代码中的功能是一样的,只是包罗了更多的上下文信息,如宏定义和类型定义。通太过析.i文件,可以更好地理解编译器怎样处理和理解源代码。
(第2章0.5分)

第3章 编译

3.1 编译的概念与作用

概念:编译是将高级编程语言编写的源代码转换为呆板语言(或中间代码)的过程,这一过程由编译器完成。编译包括多个阶段,如词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成,最终生成可执行文件或目标文件。
作用:编译的主要作用是将人类可读的源代码转换为盘算机可以执行的呆板代码,从而使步伐可以或许在盘算机上运行。编译器在此过程中还进行错误查抄和代码优化,提高步伐的精确性和运行服从,并将步伐分解为可管理的模块,便于调试和维护
3.2 在Ubuntu下编译的下令

https://i-blog.csdnimg.cn/blog_migrate/56730a285604d80366c5cb660250dca2.png
图 3.0.1编译
输入指令:gcc -S hello.i -o hello.s 生成hello.s文件
3.3 Hello的编译结果剖析

3.3.1文件名指令
指示该汇编代码对应的源文件 hello.c
https://i-blog.csdnimg.cn/blog_migrate/a1486c86edcc21e3fec4834e6737ebc2.png
图 3.0.2.file
3.3.2 .section .rodata定义只读数据段
https://i-blog.csdnimg.cn/blog_migrate/e4a1fbb6c3eda28f65ef7b19bd588a9c.png
图 3.0.3只读数据段
包罗两个字符串常量:
.LC0 是中文提示信息 "用法: Hello 学号 姓名 手机号 秒数!\n" 的 UTF-8 编码字符串。.LC1 是格式字符串 "Hello %s %s %s\n"。
3.3.3主函数
main 函数标记为全局可见,.globl main 指示链接器全局符号
https://i-blog.csdnimg.cn/blog_migrate/1e68073f29b059cc83716460adb281f9.png
图 3.0.4主函数
endbr64 是用于Intel CET的指令;
pushq %rbp 生存旧的基址指针,movq %rsp, %rbp 设置新的基址指针,subq $32, %rsp 为局部变量在栈上分配32字节空间。
3.3.4处理参数argc和argv
https://i-blog.csdnimg.cn/blog_migrate/ec7b74e4bf81d8e445ff5363947b415e.png
图 3.0.5argc.argv
movl %edi, -20(%rbp) 将argc生存到局部变量-20(%rbp),movq %rsi, -32(%rbp) 将argv生存到局部变量-32(%rbp),cmpl $5, -20(%rbp) 比较argc是否等于5,je .L2 如果 argc 等于5,跳转到 .L2;
https://i-blog.csdnimg.cn/blog_migrate/78196010fa21fe05301f3e9c30793106.png
如果 argc 不等于5:leaq .LC0(%rip), %rax 加载 .LC0 的地点到 %rax,movq %rax, %rdi 设置 puts 的参数,call puts@PLT 调用 puts,movl $1, %edi 设置 exit 的参数为1,call exit@PLT 调用 exit 并退出步伐
3.3.5循环
循环初始化、循环变量i
https://i-blog.csdnimg.cn/blog_migrate/60e5eff0564728e8c998289e33115b5f.png
图 3.0.6初始化循环变量
.L2: 是循环的开始标签,movl $0, -4(%rbp) 初始化循环变量 i 为0,jmp .L3 跳转到循环条件查抄。
循环体
https://i-blog.csdnimg.cn/blog_migrate/1532486ff08191eb4dde0133c475b330.png
图 4.0.7L4循环体
.L4: 是循环体的开始标签,将 argv 的基地点加载到 %rax,分别将argv的地点加载到%rcx%rdx%rsi中,加载 .LC1 的地点到 %rax,设置 printf 的格式字符串参数,设置 printf 的 variadic 参数,调用printf;
https://i-blog.csdnimg.cn/blog_migrate/40255adde0d2740aeabee16efcb288f0.png
图 3.0.8printf函数
https://i-blog.csdnimg.cn/blog_migrate/d3b0b62941c1c148eae41afb17697d25.png
图 3.0.9for循环
将 argv 的基地点加载到 %rax,将 argv 的地点加载到 %rax,将 argv 的内容加载到 %rdi,调用 atoi 将字符串转换为整数,
https://i-blog.csdnimg.cn/blog_migrate/21433c8580dd5b4a540bb7e50edc123e.png
图 3.0.10sleep函数
将转换后的整数设置为 sleep 的参数,call sleep@PLT 调用 sleep,addl $1, -4(%rbp) 增长循环变量 i。
循环条件查抄
https://i-blog.csdnimg.cn/blog_migrate/fe0c80ecfa2e58db3815d15e6a6ace5a.png
图 3.0.11循环条件查抄
.L3: 是循环条件查抄标签,cmpl $9, -4(%rbp) 比较循环变量 i 是否小于等于9,jle .L4 如果是,跳转到循环体 .L4。
https://i-blog.csdnimg.cn/blog_migrate/6f0ea57c4021db8d090fd221c3675039.png
图 3.0.12输入
循环结束后,call getchar@PLT 调用 getchar,movl $0, %eax 设置返回值为0,leave 恢复旧的基址指针并调整栈指针,ret 返回。
3.4 本章小结

通过这些步骤,C代码被编译器转换为汇编代码,生存了原始逻辑并适应目标平台的指令集和调用约定。
数据类型处理:整型(如 int)变量 i 使用32位寄存器(movl 操作)。指针类型(如 char*)使用64位寄存器(movq 操作)。
算术和逻辑操作:如循环中的 i++ 被编译为 addl $1, -4(%rbp)。
函数调用:如 printf、sleep、atoi 等函数调用遵循函数调用约定,将参数放入适当的寄存器并使用 call 指令。
控制流:如 if 语句和 for 循环使用条件跳转指令(cmp、je、jmp、jle)实现。
(第3章2分)

第4章 汇编

4.1 汇编的概念与作用

概念:汇编是将汇编语言代码转换为呆板代码的过程,这一过程由汇编器完成。汇编语言是一种低级编程语言,它使用简洁的符号和助记符表示呆板指令,可以或许直接操作硬件,且与特定的处理器架构精密相关。
作用:汇编的作用是将汇编语言代码转化为盘算机可以或许执行的呆板语言指令,使步伐可以在硬件上运行。通过汇编,步伐员可以进行精致的硬件控制、优化步伐性能,并在系统编程和嵌入式编程中实现对底层硬件的直接访问。
注意:这儿的汇编是指从 .s 到 .o 即编译后的文件到生成呆板语言二进制步伐的过程。
4.2 在Ubuntu下汇编的下令

https://i-blog.csdnimg.cn/blog_migrate/0e3c3c3a9ce8f33f6ee97e6060aa3431.png
图 4.0.1汇编
输入指令:gcc -c -m64 -no-pie -fno-PIC -c -o hello.o hello.s 生成hello.o文件
4.3 可重定位目标elf格式

https://i-blog.csdnimg.cn/blog_migrate/6614c83da5c16e1aa4e6a0fea1bc9c1e.png
图 4.0.2可重定位目标elf格式
输入指令:readelf -a hello.o > hello.elf 生成hello.elf
4.3.1ELF头
Magic: 7f 45 4c 46 是 ELF 文件的魔数,确认了这是一个 ELF 文件。
这是一个 64 位的 ELF 文件,数据编码方式为小端序。当前版本的 ELF 文件格式是1 (current),实用于 UNIX System V,ABI 版本号是0,这是一个可重定位文件,通常用于目标文件,目标系统架构是 x86-64,对于可重定位文件,入口点地点为 0,没有步伐头。节头表的起始位置是1088 (bytes into file),没有特殊标记。ELF 文件头的巨细是 64 (bytes),每个节头的巨细 64 (bytes),统共有 14 个节头,节头字符串表在第 13 个节中。
https://i-blog.csdnimg.cn/blog_migrate/51ff18b52a6cfc64dd57377291102c21.png
图 4.0.3ELF头
4.3.2节头
包罗
[号] 名称              类型             地点              偏移量
       巨细              全体巨细          旗标   链接   信息   对齐
.text节:以编译的呆板代码,类型为PROGBITS,意为步伐数据,旗标为AX,即权限为分配内存、可执行。
.rela.text节:一个.text借中的列表,当链接器把这个目标文件和其他文件组适时,必要修改这些位置。
.data节:已初始化的静态和全局C变量。类型为PROGBITS,意为步伐数据,旗标为WA,及权限为可分配可写。
.bss节:未初始化的全局和静态C变量,以及全部被初始化为0的全局或静态变量。在目标文件中这个节不占据实际的空间,它仅仅是一个占位符。类型为NOBITS,意为临时没有存储空间,旗标为WA,即权限为可分配可写。
.rodata节:存放只读数据,比方printf中的格式串和开关语句中的跳转表。类型为PROGBITS,意为步伐数据,旗标为A,即权限为可分配。
.comment节:包罗版本控制信息。
.note.GNU_stack节:用来标记executable stack(可执行堆栈)。
.eh_frame节:处理异常。
.rela.eh_frame节:.eh_frame的重定位信息。
.shstrtab节:该区域包罗节区名称。
.symtab节:一个符号表,它存放在步伐中定义和引用的函数和全局变量的信息。
.strtab节:一个字符串表,其内容包括.symtab和.debug节中的符号表,以及节头部的节名字。
https://i-blog.csdnimg.cn/blog_migrate/a5cb7e8b9fbe4147a42a9dffcf838bf1.png
图 4.0.4节头
4.3.3步伐头
本文件中没有步伐头。
4.3.4重定位节
 .rela.text 和 .rela.eh_frame 包罗重定位条目。
https://i-blog.csdnimg.cn/blog_migrate/e85745bd02bc77de998d475b51598f1d.png
图 4.0.5重定位节
4.3.5符号表
 .symtab 包罗 11 个条目,包括文件名、段名和全局符号 main。
https://i-blog.csdnimg.cn/blog_migrate/d7e3b005d411d179c4f0c04bfcca3120.png
图 4.0.6符号表
4.4 Hello.o的结果剖析

https://i-blog.csdnimg.cn/blog_migrate/5c77776c56a3d52cbe8ce1133de978a9.png
图 4.0.7hello.o反汇编
输入指令:objdump -d -r hello.o >hello.txt 生成helloo.txt文件
 分析hello.o的反汇编,并请与第3章的 hello.s进行对照分析。说明呆板语言的构成,与汇编语言的映射关系。特殊是呆板语言中的操作数与汇编语言差别等,特殊是分支转移函数调用等。
呆板语言是盘算机可以直接执行的一种语言,它使用二进制代码表示指令和数据。呆板语言中的指令由两部分构成:操作码:指定要执行的操作类型,比方加法、乘法、加载数据等。操作数:包罗在指令中的数据或地点,用于指定操作码要操作的内容。汇编语言是一种更高级的语言,它使用助记符和符号来代替呆板语言中的二进制指令码和内存地点。汇编语言与呆板语言之间的映射关系由汇编器负责处理。汇编器将汇编语言源代码转换为对应的呆板语言指令序列。
在汇编语言中会有特定的指令,它们直接对应于呆板语言中的分支跳转和函数调用指令。汇编语言的这些指令会被汇编器转换成相应的呆板语言指令,从而实现步伐控制流的转移和函数调用功能。
https://i-blog.csdnimg.cn/blog_migrate/4fd1e0a32edaa763b276ac6cd251da87.png
图4.0.8调用函数
https://i-blog.csdnimg.cn/blog_migrate/3d35463487e8bd0fbcfb7d993be20bb5.png
图 4.0.9无条件跳转到循环开始处
4.5 本章小结

由于直接生成的.o为二进制文件无法直接访问,我们通过查看ELF格式,以及用反汇编后得到的代码进行分析,发现各种操作中的地点被具体化,进一步了解了hello。
(第4章1分)

第5章 链接

5.1 链接的概念与作用

概念:链接是将编译生成的目标文件(hello.o)和库文件联合起来,生成一个可执行文件(hello)的过程,这一过程由链接器完成。链接过程包括符号剖析、地点重定位和合并多个目标文件及库文件,最终生成一个完整的、可以独立运行的可执行文件。
作用:链接的主要作用是将各个独立的代码模块(目标文件)和库函数联合起来,办理跨模块的符号引用,确保全部函数和变量都有定义。通过链接,步伐得以整合成一个同一的可执行文件,从而可以在盘算机上加载和运行,支持代码重用和模块化编程,提高开发服从和步伐的可维护性。注意:这儿的链接是指从 hello.o 到hello生成过程。
5.2 在Ubuntu下链接的下令

https://i-blog.csdnimg.cn/blog_migrate/7aaf074a2171224df302dd5d59ffcf5f.png
图 5.0.1链接
输入如图指令,生成可执行文件hello
5.3 可执行目标文件hello的格式

https://i-blog.csdnimg.cn/blog_migrate/05d611fa9bcc5df2e06f5dee4d118ed5.png
图 5.0.2hello的ELF格式
输入指令:readelf -a hello >hello1.elf 生成hello1.elf
分析hello的ELF格式,用readelf等列出其各段的基本信息,包括各段的起始地点,巨细等信息。
5.3.1ELF头
类型为:EXEC(可执行文件)入口点地点: 0x4010f0步伐头起点: 64 bytes节头起点: 13560 bytes步伐头巨细: 56 bytes步伐头数目: 12节头巨细: 64 bytes节头数目: 27节头字符串表索引: 26
5.3.2节头
.interp: 存放步伐表明器路径 地点: 0x4002e0偏移: 0x2e0巨细: 0x1c
.text: 包罗步伐的代码段。地点: 0x4010f0偏移: 0x10f0巨细: 0xd8
.dynamic: 动态链接信息。地点: 0x403e50偏移: 0x2e50巨细: 0x1a0
.data: 初始化数据段。地点: 0x404048偏移: 0x3048巨细: 0x4
5.3.3步伐头
PHDR:偏移: 0x40VirtAddr: 0x400040FileSiz: 0x2aMemSiz: 0x2a0标记: R
INTERP:偏移: 0x2e0VirtAddr: 0x4002e0FileSiz: 0x1cMemSiz: 0x1c标记: R
表明器: /lib64/ld-linux-x86-64.so.2
5.3.4动态节
NEEDED: 共享库 libc.so.6
INIT: 初始化段地点 0x401000
5.3.5符号表
puts@GLIBC_2.2.5
printf@GLIBC_2.2.5
5.3.6重定位节 (Relocation Section)
重定位节包罗了必要在加载时修正的地点:
.rela.dyn.rela.plt

5.4 hello的虚拟地点空间

使用edb加载hello,查看本进程的虚拟地点空间各段信息,并与5.3对照分析说明。
https://i-blog.csdnimg.cn/blog_migrate/1242fa78c8429d2a8edb57ff4bb5be17.png
图 5.0.3虚拟地点空间
Data Dump区域显示了虚拟地点空间的信息,可以看到hello步伐从虚拟空间0x401000载入,查看Symbols发现是.init的地点,与5.3中节头部表中的地点同等。
https://i-blog.csdnimg.cn/blog_migrate/2718e20320a449c1091b61f41ab8e274.png
https://i-blog.csdnimg.cn/blog_migrate/02b754fd229c219e7b34ccad59ef0eb3.png
图 5.0.4symbolviewer
打开edb,加载hello,打开symbolviewer查看虚拟地点各段信息。

5.5 链接的重定位过程分析

https://i-blog.csdnimg.cn/blog_migrate/7203e81712b29765dc2dba6a2049ab4a.png
图 5.0.5hello反汇编
输入指令:objdump -d -r hello >hello1o.txt 生成hello1o.txt,分析hello与hello.o的差别,说明链接的过程。
https://i-blog.csdnimg.cn/blog_migrate/932827b0510a256b9c1df025b9fb4a08.png
图 5.0.6反汇编文件
与可重定位目标文件hello.o的反汇编的结果相比,主要有两个地方差别,一是扩充了许多函数代码,包括步伐加载后执行main前的一些准备工作,以及hello必要用到的一些库函数的定义等;二是在main中,原本在hello.o中等候重定位而临时置0的地点操作数被设置为了虚拟地点空间中真正的地点。
5.6 hello的执行流程

使用gdb/edb执行hello,说明从加载hello到_start,到call main,以及步伐终止的全部过程(主要函数)。请列出其调用与跳转的各个子步伐名或步伐地点。
从加载hello到_start
步伐名
ld -2.27.so!_dl_start
ld-2.27.so!_dl_init
hello!start
到call main
步伐名
libc-2.27.so!_libc_start_main
libc-2.27.so!_al_fixup
libc-2.27.so!_libc_csu_init
libc-2.27.so!_setjmp
hello!main

到结束
步伐名
hello!puts@plt
hello!exit@plt
ld-2.27.so!_dl_fixup
ld-2.27.so!exit
5.7 Hello的动态链接分析

分析hello步伐的动态链接项目,通过edb/gdb调试,分析在动态链接前后,这些项目标内容变化。
在进行动态链接时,共享库中的代码和数据并未直接合并到可执行文件 hello 中。相反,动态链接器在加载 hello 文件时,对共享目标文件中相关模块内的代码和数据进行重定位。同时,动态链接器会加载共享库,并将其合并到 hello 文件中,生成完全链接的可执行目标文件。这一过程使得步伐可以或许在运行时动态地获取共享库中的函数和数据,实现了更灵活、更高效的代码共享和重用。
https://i-blog.csdnimg.cn/blog_migrate/cca25bfa9dc249cfde707137959b5552.png
图 5.0.700403000
dl_init前:404008和404010处为空
动态链接采取耽误加载的方式,只有在必要调用函数时才进行符号映射。系统利用偏移量表(GOT)和过程链接表(PLT)来实现动态链接。GOT 中存储函数的目标地点,并为每个全局函数创建副本函数,而这些副本函数位于 PLT 中。每次函数调用时,步伐先跳转到 PLT 中的副本函数,然后再由副本函数跳转到实际的函数目标地点,实现了耽误加载和符号映射。
dl_init后:加载时动态连接器重定位这两个条目,写入了精确的地点。
https://i-blog.csdnimg.cn/blog_migrate/9c4dd63f0646f1a46cd4b1d4d86cba11.png
图 5.0.800404000
5.8 本章小结

本章简要先容了linux下链接的相关下令,先容了生成的二进制可执行文件,对其可重定位目标elf格式进行了分析,并分析了其执行流程和动态连接过程。
(第5章1分)


第6章 hello进程管理

6.1 进程的概念与作用

概念:进程是一个执行中步伐的实例,系统的每个步伐都运行在某个进程的上下文中,上下文是由步伐精确运行所需的状态构成的。包括存放在内存中的步伐的代码和数据,它的栈、通用目标寄存器的内容、步伐计数器、环境变量以及打开文件形貌符的集合。
作用:提供给应用步伐一个独立的逻辑控制流,它提供一个假象,好像我们的步伐独占地使用处理器;提供给应用步伐一个私有的地点空间,它提供一个假象,好像我们的步伐独占地使用内存系统。
6.2 简述壳Shell-bash的作用与处理流程

作用:
下令表明器:表明用户输入的下令,并将其传递给操作系统内核执行。
脚本执行:运行脚本文件,这些文件包罗一系列下令和控制结构(如条件语句、循环等),用于自动化任务。
环境管理:管理用户的工作环境,包括设置环境变量、路径、别名等。
步伐控制:提供工具来启动、克制和控制步伐的执行。
输入输出重定向:允许用户重定向下令的输入输出。
处理流程:
读取用户输入的下令行或脚本文件中的下令。将输入的下令行分解为令牌,根据Shell的语法规则,将令牌剖析成可以执行的下令结构。将下令中的变量更换为其实际值,别名更换为其对应的下令。执行下令更换操作。 根据重定向符号(如>、<、|),设置下令的输入输出流。重定向可以将下令的输出写入文件、从文件读取输入或将输出通过管道传递给另一个下令。调用操作系统内核,创建一个子进程来执行下令。如果是内建下令,Shell会直接在当进步程中执行。下令执行完毕后,吸收并处理下令的返回状态,并将其存储在特殊变量中。对于交互式Shell,会返回到步骤1,等候用户输入新的下令;对于脚本文件,会继续读取并执行下一行下令,直到文件结束。
6.3 Hello的fork进程创建过程

https://i-blog.csdnimg.cn/blog_migrate/15d55072cd00ed62810c6fca3c30d9e5.png
图 6.0.1创建进程

6.4 Hello的execve过程

在shell新创建的子进程中,execve函数加载并运行可执行目标文件hello,且带参数列表argv和环境变量列表envp,只有出现错误是,execve才会返回到调用步伐。
在execve加载hello之后,调用启动代码来执行hello,新的代码和数据段初始化为可执行文件的内容,跳转到_start调用libc_start_main设置栈,并将控制传递给新步伐的主函数。
https://i-blog.csdnimg.cn/blog_migrate/d1307e5133272ba579eb1aeac09fbf9c.png
图 6.0.2新步伐启动后的栈结构
6.5 Hello的进程执行

当一个新的进程被创建时,操作系统为其分配必要的资源和空间。这包括分配一个唯一的进程标识符(PID)、内存空间、寄存器状态等。hello步伐的执行开始于进程创建和加载阶段。每个进程都有自己的上下文信息,包括寄存器内容、内存映像、打开的文件形貌符、信号处理器状态等。这些信息定义了进程的当前状态和运行所需的全部数据。hello进程在执行过程中,其上下文信息将随着执行的差别阶段和操作系统调理的影响而变化。操作系统使用调理算法来决定何时以及怎样分配CPU时间片给差别的进程。每个进程都被分配一个时间片,在该时间片结束之前,进程将继续执行。hello进程会根据调理算法的具体战略(如轮转调理、优先级调理等)得到CPU时间。进程执行时,操作系统会根据必要将进程从用户态切换到焦点态(也称为内核态)。用户态下的进程只能访问受限资源,而焦点态下的进程可以执行特权指令、访问全部资源并执行操作系统服务。比方,当hello进程执行系统调用(如printf)时,它会哀求操作系统切换到焦点态,以便内核执行必要的IO操作或其他服务。
加载和执行:hello进程被加载到内存并从其入口点(如0x4010f0)开始执行。
系统调用:当hello步伐调用printf函数时,它将发起一个系统调用哀求,这会导致进程从用户态切换到焦点态,内核负责在终端上打印消息。
时间片耗尽:如果hello进程的时间片用尽,操作系统会暂停其执行,并将CPU分配给下一个等候执行的进程。
上下文切换:当操作系统决定重新调理hello进程时,它会生存当进步程的上下文信息,切换到下一个进程的上下文,并恢复其状态,使其可以继续执行。
进程结束:当hello进程执行完全部指令并返回时,或者通过调用exit系统调用显式终止时,操作系统会释放其分配的资源,包括内存空间、文件形貌符等,并标记进程为已终止状态。
https://i-blog.csdnimg.cn/blog_migrate/291b90cbb097cccc07b2dea76f9c19ad.png
图 6.0.3上下文切换
6.6 hello的异常与信号处理

步伐运行过程中可以按键盘,如不绝乱按,包括回车,Ctrl-Z,Ctrl-C等,Ctrl-z后可以运行ps  jobs  pstree  fg  kill 等下令,请分别给出各下令及运行结截屏,说明异常与信号的处理。
6.6.1不绝乱按

https://i-blog.csdnimg.cn/blog_migrate/1ec8bd4f255c22d74d205e49e0dd3a89.png
图 6.0.4乱按
https://i-blog.csdnimg.cn/blog_migrate/a34a71a0dab147f05edf75763e1267fc.png
图 6.0.5乱按结果
输入存储到缓冲区,步伐正常运行。
6.6.2回车
https://i-blog.csdnimg.cn/blog_migrate/939e1e746d43c054f07c7ac6218da174.png
图 6.0.6回车
无影响
6.6.3Ctrl C  Ctrl Z
https://i-blog.csdnimg.cn/blog_migrate/b1b746b89300f6986d8dc04829318ec3.png
图 6.0.7CtrlC Z
Ctrl-C:步伐收到SIGINT信号终止。
Ctrl-Z:步伐收到SIGSTP信号暂停
6.6.4CtrlZ后PS
https://i-blog.csdnimg.cn/blog_migrate/1b2ae9eb96784fc11cdd69f5b960ee13.png
图 6.0.8PS
显示了暂停中的hello进程的信息。
6.6.5CtrlZ后jobs
https://i-blog.csdnimg.cn/blog_migrate/4ac2d3a645b657cd793fc1beec076d89.png
图 6.0.9jobs
显示暂停的进程
6.6.6CtrlZ后pstree
https://i-blog.csdnimg.cn/blog_migrate/3250b9003d288ae77d40101e0738d7e2.png
图 6.0.10pstree
输入pstree, 显示进程树,显示全部进程的情况
6.6.7CtrlZ后fg
https://i-blog.csdnimg.cn/blog_migrate/00752ce4a8e628ac69d4a76f77712c25.png
图 6.0.11fg
使第一个后台作业变成前台作业,这会让hello变为前台执行
6.6.8CtrlZ后kill
https://i-blog.csdnimg.cn/blog_migrate/ab467ec1037c62c07d64fad44361cc8a.png
图 6.0.12kill
杀死hello进程
6.7本章小结

本章简要先容了进程的概念和作用,fork()、execve()函数的使用等,展示了hello进程的创建,执行,终止以及各个下令,如ps,jobs等的作用。
(第6章1分)

第7章 hello的存储管理

7.1 hello的存储器地点空间

编译阶段:编译器将hello.c源代码编译为目标文件(如hello.o),生成与逻辑地点相关联的代码段和数据段。
链接阶段:链接器将目标文件链接为可执行文件hello,此时生成了与线性地点相关联的代码段和数据段。
运行阶段:当操作系统加载hello步伐时,将步伐的线性地点映射为虚拟地点,并使用分页机制将虚拟地点转换为物理地点,最终访问系统的实际内存位置。
7.1.1. 逻辑地点
逻辑地点是步伐中使用的地点空间,通常由步伐员定义,用于访问内存中的数据和指令。在编译和链接阶段,步伐中的变量和代码被编译器和链接器处理,生成逻辑地点。
7.1.2. 线性地点
线性地点是逻辑地点颠末操作系统的地点转换机制(如分段或分页机制)转换后得到的地点。在当代操作系统中,通常使用分页机制将逻辑地点转换为线性地点。
7.1.3. 虚拟地点
虚拟地点是进程所见到的地点空间,它包括步伐的逻辑地点和由操作系统管理的内存地点。虚拟地点空间对每个进程都是独立的,进程可以在虚拟地点空间中自由访问,而不必要关心物理内存的实际位置。
7.1.4. 物理地点
物理地点是内存中存储单元的真实地点,它指的是存储器芯片上的特定位置。操作系统通过地点映射机制(如页表)将虚拟地点转换为物理地点,从而最终访问内存中的数据和指令。
7.2 Intel逻辑地点到线性地点的变换-段式管理

根据逻辑地点中的段选择子,确定要访问的段形貌符。段选择子中的段索引指定了形貌符表(GDT或LDT)中的一个条目。使用段选择子中的段索引,从GDT或LDT中获取对应的段形貌符。段形貌符中包罗了段的基地点和段的巨细等信息。对于32位系统,段的基地点由段形貌符的基地点字段和偏移字段(offset)构成。
将逻辑地点中的偏移量与段形貌符中的基地点进行加法运算,得到线性地点。线性地点即为CPU可直接访问的地点空间。在实际访问内存时,操作系统将线性地点转换为物理地点。这一步通常涉及到分页机制的介入,通过页表将线性地点映射到物理地点。
7.3 Hello的线性地点到物理地点的变换-页式管理

CPU使用线性地点中的高10位作为页目次表索引,从页目次表中获取对应的页目次项(PDE)。从页目次项(PDE)中获取页表的基地点,并使用线性地点中的中间10位作为页表索引,从页表中获取对应的页表项(PTE)。从页表项(PTE)中获取物理页框号(PFN),将线性地点中的低12位(偏移量)与物理页框号进行组合,得到最终的物理地点。
https://i-blog.csdnimg.cn/blog_migrate/ab084797401b7551d73a9f05216fc71b.png
图 7.0.1基于页表的地点翻译
7.4 TLB与四级页表支持下的VA到PA的变换

TLB和四级页表是协同工作的,TLB的作用是加速地点转换,淘汰对页表的访问次数,从而提高性能。四级页表的作用是提供了虚拟地点到物理地点的具体映射关系,是TLB未命中时的备用。
地点转换的完整过程为CPU生成一个虚拟地点。首先查抄TLB中是否有该虚拟地点的映射关系。如果TLB命中,则直接从TLB中获取物理地点。如果TLB未命中,则通过多级页表(页目次表、页表)获取物理地点,并将新的映射关系加载到TLB中。通过TLB和多级页表的联合使用,当代操作系统可以有效地管理和保护内存,同时提供快速的地点转换功能,以满足差别步伐对内存地点访问的需求。
https://i-blog.csdnimg.cn/blog_migrate/dd27220a31a57a417c4c7dc3c63fc0c7.png
图 7.0.2多级页表
7.5 三级Cache支持下的物理内存访问

在拥有三级缓存支持的系统中,物理内存访问履历了多个阶段。首先,当CPU执行指令或加载数据时,会先查抄最快速的L1缓存,如果缓存未命中,则查抄次级的L2缓存。如果L2缓存也未命中,则会查找更大、更慢速的L3缓存。如果L3缓存中找不到所需数据,则CPU将从主存(物理内存)中获取数据。整个过程中,缓存的层级渐渐增长,速率渐渐减慢,但通过层层缓存的分级访问,系统可以或许在包管快速响应的同时,有效地管理数据的访问与存储。
7.6 hello进程fork时的内存映射

当一个进程(比方名为hello的进程)调用fork()创建子进程时,操作系统会将父进程的地点空间完全复制一份给子进程,这包括代码段、数据段、堆、栈以及其他映射的内存区域。这种内存映射的复制是通过写时复制(copy-on-write)实现的,意味着父子进程共享相同的物理页面,直到其中一个进程试图修改这些页面的内容。这种机制包管了在fork()操作后,系统内存的有效利用,同时避免了不必要的内存复制开销。
7.7 hello进程execve时的内存映射

当hello进程调用execve()函数执行新步伐时,操作系统会将当进步程的地点空间清除,然后重新创建新步伐的地点空间映射。这个过程包括加载新步伐的代码段、数据段、共享库以及其他必要的映射区域,以及设置新步伐的堆栈和参数。execve()系统调用会更换当进步程的内存映射,将其转换为新步伐的内存布局,从而开始执行新步伐。
7.8 缺页故障与缺页停止处理

缺页故障指的是当步伐访问的页面不在主存中,必要从磁盘中加载到主存时发生的情况。当CPU访问一个缺页时,会触发缺页停止。操作系统的缺页停止处理步伐首先会查抄访问的页面是否已经在主存中,如果不在,则根据页面表找到对应的页面位置,并将其从磁盘加载到主存中的空闲页面上。一旦页面加载完成,操作系统更新页表,使得步伐可以重新执行被停止的指令,继续执行。
https://i-blog.csdnimg.cn/blog_migrate/83e51d6ba789576f2032cf98806cb839.png
图 7.0.3缺页
https://i-blog.csdnimg.cn/blog_migrate/252cc7dccc631a20b3cedf33dc6c5b3f.png
图 7.0.4缺页停止处理
7.9动态存储分配管理

当使用`printf`函数输出格式化字符串时,如果字符串中包罗可变的部分(比方变量值),`printf`必要在运行时动态地分配内存来存储这些可变部分的字符串表示。这通常涉及到调用`malloc`函数来分配富足巨细的内存来存储格式化后的字符串。动态内存管理的基本方法包括使用`malloc`、`calloc`或`realloc`函数来分配内存,并使用`free`函数来释放已分配的内存。战略方面,常见的包括合理选择内存分配算法(如最先适应、最佳适应、最坏适应),管理内存碎片化问题,避免内存泄漏,并在必要时使用内存池等技术来优化内存管理服从。
7.10本章小结

本章简述了盘算机中的各类地点及他们之间的相互转换,并探究了盘算机的虚拟内存系统内部的工作原理,从内存角度重新审阅了前面的若干知识,如fork、execve函数,最后表明了动态内存管理的基本方法与战略。
(第7章 2分)

第8章 hello的IO管理

8.1 Linux的IO设备管理方法

设备的模子化:全部的 I/O 设备(比方网络、磁盘和终端)都被模子化为文件,而全部的输入和输出都被当作对相应文件的读和写来执行

设备管理:Linux内核有一个简朴、低级的接口,称为Unix I/O,使得全部的输入和输出都能以一种同一且同等的方式来执行。

8.2 简述Unix IO接口及其函数

Unix IO接口提供了一套标准化的方法,使用户步伐可以或许与操作系统内核进行文件和设备的输入输出交互。其主要函数包括`open`用于打开文件,`read`和`write`用于读写文件内容,`close`用于关闭文件,`lseek`用于定位文件指针,以及`ioctl`用于设备控制等。通过这些函数,步伐可以管理文件形貌符,进行文件和设备的操作,并进行错误处理和状态查询,提供了强盛而灵活的IO操作能力,是Unix系统中焦点的功能之一。
8.3 printf的实现分析

https://www.cnblogs.com/pianist/p/3315801.html
从vsprintf生成显示信息,到write系统函数,到陷阱-系统调用 int 0x80或syscall等.
字符显示驱动子步伐:从ASCII到字模库到显示vram(存储每一个点的RGB颜色信息)。
显示芯片按照刷新频率逐行读取vram,并通过信号线向液晶显示器传输每一个点(RGB分量)。
8.4 getchar的实现分析

异步异常-键盘停止的处理:键盘停止处理子步伐。接受按键扫描码转成ascii码,生存到系统的键盘缓冲区。
getchar等调用read系统函数,通过系统调用读取按键ascii码,直到接受到回车键才返回。
8.5本章小结

在本章我们分析了Linux的IO设备管理方法,并对UnixIO接口及其函数进行了简朴先容;最后通过printf和getchar两个底子函数的实现,让我们看到了linux可以或许高效运行的上风所在:进行简朴高效的IO管理。
(第8章1分)
结论

hello所履历的过程:
     hello最初是一个C语言源步伐hello.c,即program。
     ①预处理:对带#的指令剖析,生成hello.i文件,表明预处理指令。
     ②编译:履历编译后,得到hello.s,即汇编语言级代码。
     ③汇编:把汇编语言转换成呆板代码,生成重定位信息,生成hello.o。
     ④链接:与动态库链接,生成可执行文件hello。
     ⑤创建进程:在Shell利用./hello运行hello步伐,父进程通过fork函数为hello创建进程。
     ⑥加载步伐:通过加载器,调用execve函数,删除原来的进程内容,加载现在进程的代码、数据比及进程自己的虚拟内存空间。
     运行hello时,内存管理单元MMU、翻译后备缓冲器TLB、多级页表机制、三级Cache守望相助,完成对地点的哀求。
     异常处理机制包管了hello对异常信号的处理,使步伐安稳运行。
     当hello运行完毕,Shell父进程回收hello,内核删除为这个进程创建的全部数据结构。
     hello.c步伐从创建到结束的生命周期涉及了创建和编辑源代码、编译、链接、运行和结束的多个阶段。这个过程涉及了多个工具和组件的协作,包括编辑器、编译器、链接器以及操作系统。每个阶段都对应着特定的任务和输出,最终形成了一个可以执行并输出的步伐。
(结论0分,缺失 -1分,根据内容酌情加分)

附件

列出全部的中间产物的文件名,并予以说明起作用。
hello.i                           处理hello.c生成的文件
hello.s                           对hello.i 进行编译生成的文件
hello.o                           对hello.s 进行汇编生成的文件
hello.elf                          对hello.o 进行readelf生成的文件
helloo                           对hello 进行objdump反汇编生成的文件
hello                            对hello.o进行链接生成的文件
hello.out.asm                     对hello进行objdump反汇编生成的文件
hello1.elf                        对hello 进行readelf生成的文件

(附件0分,缺失 -1分)

参考文献

为完本钱次大作业你翻阅的册本与网站等
  林来兴. 空间控制技术. 北京:中国宇航出版社,1992:25-42.
  辛希孟. 信息技术与信息服务国际研讨会论文集:A集. 北京:中国科学出版社,1999.
  赵耀东. 新时代的工业工程师. 台北:天下文化出版社,1998 . http://www.ie.nthu.edu.tw/info/ie.newie.htm(Big5).
  谌颖. 空间交会控制理论与方法研究. 哈尔滨:哈尔滨工业大学,1992:8-13.
  KANAMORI H. Shaking Without Quaking. Science,1998,279(5359):2063-2064.
  CHRISTINE M. Plant Physiology: Plant Biology in the Genome Era. Science,1998,281:331-332. http://www.sciencemag.org/cgi/ collection/anatmorp.
(参考文献0分,缺失 -1分)


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: HIT-CSAPP大作业 步伐人生-Hello‘s P2P