和其他的字符串,以及一个数组,即为argv。Argc是main函数的第一个参数,剖析程序中的movl %edi, -20(%rbp)可知,%rdi中的内容作为第一个参数,赋给argc并被存放在-20(%rbp)中,直接引用即可。局部变量i被生存在栈地点-4(%rbp)中。其它常量被生存在.text节中。*argv是命令行参数,来自于键盘I/O设备输入。引用是通过其中的代码movq (%rax) %rax引用。对于数组的每个字符串元素已经在前文中剖析。其它字符串则存放在.string和.rodata段
赋值:对argv的赋值通过I/O进行并存储于(%rax)。
范例转换:通过调用函数atoi函数将字符串范例转换为整数范例。对应指令为call atoi@plt
算术操纵:此程序中绝大多数的算术操纵均被用来对栈进行操纵,其他则是用来在调用中使用,如addq $16,%rax。
逻辑和关系操纵:此程序中险些没有此类操纵,主要的用处使用在跳转,如jle .L4
数组/指针/结构操纵:*argv是命令行参数,来自于键盘I/O设备输入。通过间接寻址的处理。指针处理主要是针对栈指针,如sub $32,%rsp。
控制转移:.L3是一个循环,用-4(%rbp)和8对比控制跳出条件,把循环用跳转表示了。其它控制大多是是使用比力决定跳转。如.L2的内容。
函数操纵:程序hello中使用了printf/exit/sleep/getchar/puts/main等多种函数。调用方式比力类似,均是call。其中sleep执行之前把%rax传给%edi作为第一个参数。
3.4 本章小结
本章节比力具体的论述了编译的过程和其中的符号寄义,表现了很多hello.s的信息。汇编是hello程序人生的第二步。
第4章 汇编
4.1 汇编的概念与作用
汇编阶段,由汇编器as将汇编程序汇编成可重定位目标文件
作用:将文本文件转换二进制文件,即翻译成机器语言程序,并且使得生成的文件可以被重定位。
4.2 在Ubuntu下汇编的命令
图4.2.1 生成hello.o的指令
4.3 可重定位目标elf格式
分析hello.o的ELF格式,用readelf等列出其各节的根本信息,特别是重定位项目分析。
图4.3.1 hello.o的elf节
开头为一个16字节数据,分别是ELF字长、字节序、文件版本等等
图4.3.2 hello.o的其他节信息
.text节,存放已编译程序的机器代码。
.data节,存放已初始化的全局和静态C变量
.bss节,是未初始化的全局和静态C变量,不占用真正的空间
.rodata节,只读数据,比如这段程序中printf里的格式串和跳转表
.symtab节,是一个符号表,存放在程序中定义和引用的函数和全局变量的信息。
.strtab节,是一个包罗.symtab和.debug节的符号表以及节头部表的节名字
节头部表,包罗节名称,节的范例,节的属性(读写权限),节在ELF文件中所占的长度以及节的对齐方式和偏移量。
4.4 Hello.o的结果剖析
图4.4.1 hello.o的反汇编内容
图4.4.2 hello.o的反汇编内容
objdump -d -r hello.o 分析hello.o的反汇编,并请与第3章的 hello.s进行对照分析。
机器语言由二进制数构成,每条汇编语言对应一条汇编语言
Hello.o由于尚未重定位,因此函数调用call不直接对应地点,而是对应main+偏移地点的形式。此外,对于全局变量,hello.o的反汇编结果没有具体地点,而是被存放在.rela.text中的重定位信息中。
对于分支转移,hello.s直接通过.L1.L2等地点进行转移,反汇编直接通过jmp语句到段名称来转移。
4.5 本章小结
本章通过展示汇编的结果和概念,并且展示出来其中的内容,显示了可重定位目标文件,表现了很多可重定位目标文件的具体信息。汇编是hello程序人生的第三步。
第5章 链接
5.1 链接的概念与作用
链接阶段,由链接器ld将一些.o文件和动态库静态库链接,从可重定位目标文件生成一个可执行目标文件,可以被加载到内存中由系统执行。
5.2 在Ubuntu下链接的命令
图5.2.1 生成hello可执行程序的指令
5.3 可执行目标文件hello的格式
图5.3.1 hello的elf节
开头为一个16字节数据,分别是ELF字长、字节序、文件版本等等
图5.3.2 hello的其它节信息
5.4 hello的假造地点空间
图5.4.1 hello的假造地点空间信息
使用edb可以检察到地点为401000到40404c
使用edb加载hello,检察本进程的假造地点空间各段信息,并与5.3对照分析分析。
5.5 链接的重定位过程分析
图5.5.1 反汇编生成hello3.s的指令
图5.5.2 hello3.s的部分指令
hello得到的反汇编文件相较于原hello.o增加了很多节的信息
此外,hello中的地点是假造地点,并非实际地点
Hello中有一些外部库的代码,如printf@plt
hello中是通过间接寻址算法获取全局变量的信息。
5.6 hello的执行流程
图5.6.1 hello中具体的执行流程
使用gdb设置断点的当时可以寻找到其中的每一步
5.7 Hello的动态链接分析
使用readelf -S能够查询到hello的文件信息获取got信息
图5.7.1 hello中动态链接的查询
Init前的内容如图所示
图5.7.2 init前的内容
Init后的内容改用edb检察,如图所示
图5.7.3 init后的内容
5.8 本章小结
本章具体论述了链接的过程和链接前后程序的变化,链接是hello程序人生的第四步,也是代表它成为可执行程序可以被执行的开始。
第6章 hello进程管理
6.1 进程的概念与作用
进程是一个执行中的程序实例。
作用:进程给应用程序提供一个关键抽象,其中包罗
一个独立的逻辑控制流,它提供一个假象,好像我们的程序独占地使用处理器。
一个私有的地点空间,它提供一个假象,好像我们的程序独占地使用内存系统。
6.2 简述壳Shell-bash的作用与处理流程
作用:Shell是用户与操纵系统之间完成交互式操纵的一个接口程序,它为用户提供简化了的操纵。而NU组织又进一步开发Borne Again Shell,简称bash,它是Linux系统中默认的shell程序。
处理流程:(1)将用户输入的命令行进行剖析,分析是否是内置命令;
(2)若是内置命令,直接执行;若不是内置命令,则bash在初始子进程的上下文中加载和运行它。
6.3 Hello的fork进程创建过程
Shell本身就是一个进程,当它运行指令./hello时,相称于fork了一个hello子进程。
二者并发执行,并且使用了相同但是独立的地点空间,并且共享stdin和stdout文件。二者的最大差别在于PID不同。
6.4 Hexecve函数在当进步程的上下文加载并运行可执行目标文件Helloello的execve过程
execve函数在当进步程的上下文加载并运行可执行目标文件Hello,在execve加载了Hello之后,它调用启动代码。启动代码设置栈,并将控制传递给新程序的主函数,这个主函数带有环境变量envp。
6.5 Hello的进程执行
进程的上下文信息包罗通用目标寄存器、浮点寄存器、程序计数器、用户栈、状态寄存器、内核栈和各种内核数据结构。
一个进程执行他的控制流的一部分的每一个时间段叫做时间片。
在进程执行的过程中,内核可以决定抢占当进步程,并且规复一个之前被抢占的进程,这一过程称为内核调理了此进程。
在hello的程序人生中,先是由shell在用户模式执行,之后hello进程被创建,进入内核模式,调理hello进程,之后规复用户模式执行hello进程。执行结束之后触发磁盘中断,进入内核模式,由内核调理shell,再次规复用户模式。
执行过程shell和hello享有相同的时间片。
6.6 hello的非常与信号处理
非常是指控制流的突变,用来相应某种变化,分为4类。
(1)中断:异步非常,来自处理器外部的I/O设备。非常处理后会执行下一条指令;
(2)陷阱:同步非常,是执行系统调用函数的结果。函数调用结束后会执行下一条指令;
(3)故障:同步非常,由错误环境引起,如缺页,浮点非常等等。非常处理成功则重新执行该指令,否则程序终止;
(4)终止:同步非常,由致命错误造成。该非常将终止程序。
从键盘随意输入数据不影响结果输出
图6.6.1 随意输入数据的执行结果
回车:会停止进程。
图6.6.2 使用回车停止进程的执行结果
Ctrl-Z:挂起当进步程,信号是SIGTSTP,内核选择挂起进程
图6.6.3 使用Ctrl-Z挂起进程的执行结果
对应的ps检查如下
图6.6.4 使用ps检查进程的执行结果
Ctrl-C:中止当进步程,信号是SIGINT,内核选择中止进程
图6.6.5 使用Ctrl-C中止进程的执行结果
Jobs:列出当前被暂停的进程
图6.6.6 使用Jobs列出暂停进程的执行结果
Pstree:列出各个进程的树状图
图6.6.7 使用pstree列出进程的树状图的执行结果
fg:继续执行被挂起的进程
图6.6.8 使用fg继续执行被挂起进程的执行结果
Kill:杀死进程,信号是SIGKILL,内核选择杀死进程
图6.6.9 使用kill杀死进程的执行结果
6.7本章小结
本章主要介绍了四种非常和信号处理,以及非常控制流。非常和信号都是计算机运行程序的紧张概念,也是理解系统的紧张概念,照旧hello的程序人生的执行层面上的紧张环节。
结论
Hello的程序人生始于hello.c,颠末预处理,汇编,编译,链接酿成可执行文件,在shell上被执行,起于./hello的指令,终止于shell的kill指令或结束后被shell采取
通过本次的大作业,我深刻的体会了一个程序的运行过程,对半年以来计算机系统课程学习的内容有了一个深刻的掌握。在本次大作业中,我使用了edb和gdb结合的创新之处。在二者的结合之下,能够发挥二者的最大效益。
附件
hello.c 源代码
hello.i 对#预处理指令做初步处理
hello.s 汇编代码文件
hello.o 可重定位目标程序,二进制文件
hello 可执行目标程序,可用于执行
参考文献
[1] 大卫.R.奥哈拉伦 兰德尔.E.布赖恩特 深入理解计算机系统 北京:机械工业出版社, 2016.7
[2] (7条消息) Linux下 可视化 反汇编工具 EDB 根本操纵知识_hahalidaxin的博客-CSDN博客
[3] HIT-ICS2022大作业要求
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) |
Powered by Discuz! X3.4 |