2019-2020-2 20199317《Linux内核原理与分析》第二周作业
第一章 计算机工作原理
1 存储程序计算机工作模型
存储程序计算机的主要思想是将程序存放在计算机存储器中,然后按存储器中的存储程序的首地址执行程序的第一条指令,以后就按照该程序中编写好的指令执行,直至程序执行结束。
冯·诺依曼体系结构的核心是存储程序计算机。
2 x86-32汇编基础
8086CPU中总共有14个16位的寄存器(AX、BX、CX、DX、SP、BP、SI、DI、IP、FLAG、CS、DS、SS和ES),然后对应也有32位的寄存器(EAX、EBX、ECX、EDX、ESP、EBP、ESI、EDI、EIP、EFlags、CS、DS、SS、ES、FS和GS)32位寄存器只是把对应的16位寄存器扩展到了32位,并且所有开头为E的存储器,一般是32位的。
要注意的是在16位的CPU中,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址,但在32位的CPU中,32位寄存器EAX、EBX、ECX和EDX不仅可以传送数据、暂存数据保存算术逻辑运算结果,还可以作为指针寄存器,这些32位寄存器更具通用性。
以32位为主介绍一些常见的汇编指令:
寄存器寻址:movl %eax, %edx;
寄存器寻址就是操作的是寄存器,不和内存打交道,%eax,其中%开头后面跟一个寄存器名称。上述代码的含义为把寄存器%eax的内容放到%edx中。
立即寻址:movl $0x123,%edx
上述代码的意思是把0x123这个十六进制的数值直接放到EDX寄存器中。立即寻址也和内存没有关系。
直接寻址:movl 0x123, %edx
上述代码的意思是把0x123内存地址所指向的那块内存里存储的数据放到EDX寄存器里。直接寻址就是用内存地址直接访问内存中的数据。
间接寻址:movl (%ebx), %dx
间接寻址就是寄存器加个小括号。上述代码的意思是%ebx这个寄存器中存的值是一个内存地址,加个小括号表示这个内存地址所存储的数据,我们把它放到EDX寄存器中。
变址寻址: movl 4(%ebx), %edx
代码中“(%ebx)”前面出现了一个4,也就是在间接寻址的基础上,在原地址上加上一个立即数4。
还有一点需要注意,一般说来,全是大写字母的一般是Intel汇编,全是小写字母的一般是AT&T汇编。在这里代码用到的寄存器名称都遵守AT&T汇编格式采用全小写的方式。
接下来介绍几个很重要的指令:pushl/popl和call/ret。
在AT&T汇编中,pushl等效于以下汇编指令:
subl $, %esp #把堆栈的栈顶ESP寄存器的值减4,因为堆栈是向下增长的
movl %eax, (%esp) #把EAX寄存器的值放到ESP寄存器所指向的地方
在AT&T汇编中,popl等效于以下汇编指令:
movl (%esp), %eax #把栈顶的数值放到EAX寄存器中
addl $, %esp #栈顶加4,相当于栈向上回退了一个存储单元的位置
在AT&T汇编中,call指令是函数调用,调用一个地址,例如call 0x12345等效于以下汇编指令:
pushl %eip (*) #把当前的EIP寄存器压栈
movl $0x12345, %eip (*) #把0x12345这个立即数放到EIP寄存器里
然后在这里要特别注意,上面的两个动作并不存在实际对应的指令,这里用“(*)”来特别标记一下,这两个动作是由硬件一次性完成的,而且出于安全方面的原因,EIP寄存器不能被直接使用和修改。
在AT&T汇编中,ret指令跟call指令相对应,是函数返回指令,ret等效于以下汇编指令:
popl %eip (*) #把当前堆栈栈顶的一个存储单元放到EIP寄存器中
同样这里的动作并不存在实际对应的指令,这个动作也是硬件一次性完成的。
3 汇编一个简单的C语言程序并分析其汇编指令执行过程
输入ls命令可看到“Code”和“LInuxKernel”,因为目录“Code”按照“实验楼”的使用约定是保存用户编写代码的目录,所以进入“Code”目录下进行操作。

本次实验中用到的C语言代码为:
// main.c
int g(int x)
{
return x + 4;
} int f(int x)
{
return g(x);
} int main(void)
{
return f(6) + ;
}
在命令行下输入" vi main.c"命令打开文本编辑main.c文件,按"i"键进入输入状态,如下图所示:

接下来在文本编辑器VIM中按“Shift” + “:”进行文本编辑的命令模式,输入“wq”就可把代码保存到main.c中,并退出VIM编辑器,但是我遇到了一个问题就是在插入模式下按照前边操作是无效没有反应的,我的解决方案是:按ESC退出编辑模式,此时的模式为“NORMAL”模式,然后再输入冒号,接着输入“wq”,再按回车键即可,如下图所示:

然后使用gcc main.c命令编译main.c这个代码文件,这时会生成一个目标文件a.out,它是可执行的,但此时看不到任何信息,可以通过echo $?命令查看这个程序的返回值,该C语言程序的结果为11,如下图所示:

接着可以把main.c编译成一个汇编代码,可使用gcc -S -o main.s main.c -m32这个命令,如下图所示:

此时我们可以看到main.s汇编文件还有一些“.cfi_”打头的字符串以及其他以“.”打头的字符串,这些都是编译器在链接阶段所需的辅助信息,可以通过在VIM中输入“g/\.s*/d”命令删除所有以“.”打头的字符串简化main.s里的汇编代码,注意在这里VIM编辑器要在“NORMAL”模式下输入“:”,再输入“g/\.s*/d”命令,按回车键即可,如下图所示:

接着我介绍一下在上面main.s文件中新出现的汇编指令leave指令,还有与leave指令相对应的enter指令。
leave指令用来撤销函数堆栈,等价于下面两条指令:
movl %ebp, %esp
popl %ebp
enter指令用来建立函数堆栈,等价于下面两条指令:
pushl %ebp
movl %esp, %ebp
最后对该C语言程序的汇编代码进行分析:
首先假定堆栈为空栈的情况下EBP和ESP寄存器都指向栈底,而且为了简化起见,我们为栈空间的存储单元进行标号,压栈时标号加1,出栈时标号减1,如下图所示:

下面是我的分析过程:



我在分析汇编代码时movl 8(%ebp), %eax中的间接寻址产生了一个误区:我以为使用ESP寄存器变址寻址,是ESP寄存器向上移动两个标号,导致我后边的分析出了差错。后来翻看课本对间接寻址的定义,才知道是EBP寄存器存储的数值加8,ESP寄存器不移动。
4 总结
在本次学习中,我通过课本,再一次回顾了存储程序计算机工作模型以及基本的一些的汇编语言,重点是再一次深入理解了函数调用堆栈相关汇编指令,如call/ret和pushl/popl,还有leave和enter,并通过自己动手实践将一个C语言代码程序在Linux环境下运行,同时反汇编C语言程序,最后自己分析了汇编代码是如何在存储程序计算机工作模型上一步步执行的。
2019-2020-2 20199317《Linux内核原理与分析》第二周作业的更多相关文章
- 2019-2020-1 20199303<Linux内核原理与分析>第二周作业
2019-2020-1 20199303第二周作业 1.汇编与寄存器的学习 寄存器是中央处理器内的组成部份.寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令.数据和位址.在中央处理器的控制部件中 ...
- 20169219 linux内核原理与分析第二周作业
"linux内核分析"的第一讲主要讲了计算机的体系结构,和各寄存器之间对数据的处理过程. 通用寄存器 AX:累加器 BX:基地址寄存器 CX:计数寄存器 DX:数据寄存器 BP:堆 ...
- 2019-2020-1 20199314 <Linux内核原理与分析>第二周作业
1.基础学习内容 1.1 冯诺依曼体系结构 计算机由控制器.运算器.存储器.输入设备.输出设备五部分组成. 1.1.1 冯诺依曼计算机特点 (1)采用存储程序方式,指令和数据不加区别混合存储在同一个存 ...
- Linux内核原理与分析-第二周作业
写之前回看了一遍秒速五厘米:如果
- Linux内核原理与分析-第一周作业
本科期间,学校开设过linux相关的课程,当时的学习方式主要以课堂听授为主.虽然老师也提供了相关的学习教材跟参考材料,但是整体学下来感觉收获并不是太大,现在回想起来,主要还是由于自己课下没有及时动手实 ...
- 2019-2020-1 20199314 <Linux内核原理与分析>第一周作业
前言 本周对实验楼的Linux基础入门进行了学习,目前学习到实验九完成到挑战二. 学习和实验内容 快速学习了Linux系统的发展历程及其简介,学习了下的变量.用户权限管理.文件打包及压缩.常用命令的和 ...
- 2018-2019-1 20189221《Linux内核原理与分析》第一周作业
Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...
- 2020-2021-1 20209307 《Linux内核原理与分析》第九周作业
这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第九周作业> 这个作业的目标 & ...
- 2019-2020-1 20199329《Linux内核原理与分析》第十三周作业
<Linux内核原理与分析>第十三周作业 一.本周内容概述 通过重现缓冲区溢出攻击来理解漏洞 二.本周学习内容 1.实验简介 注意:实验中命令在 xfce 终端中输入,前面有 $ 的内容为 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第十二周作业
<Linux内核原理与分析>第十二周作业 一.本周内容概述: 通过编程理解 Set-UID 的运行机制与安全问题 完成实验楼上的<SET-UID程序漏洞实验> 二.本周学习内容 ...
随机推荐
- *args和**kwargs的作用
∗args的作用: *的作用有2个 打包参数(pack)和拆分参数(unpack) 函数接受实参时,按顺序分配给函数形参,如果遇到带∗的形参,那么就把还未分配出去的实参以元组形式打包(pack),分配 ...
- oop面向对象知识总结 静态成员和友元
第十一章 静态成员和友元 11.1 静态成员 1.C++类当中的静态数据成员仍借用保留字static,但是与之前的静态全局变量,静态局部变量以及静态函数没有关系. 2.静态数据成员不占用具体对象的数据 ...
- [考试反思]1031csp-s模拟测试96:常态
按照smily的说法这一场的大众分暴力分是不是265啊QwQ那我可真是个大垃圾 总算还是回归了常态. T3文件名写错,把“city.in”写成“city,in” 还好,只丢了20分. T2乱打$O(n ...
- 地精部落:dp
Description 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为 N 的山脉 H可分 为从左到右的 N 段,每段有一个独一无二的高度 Hi, ...
- 我跟上家老板说过的最后一句话:转.NET Core吧
最近几天浩子终于刚刚脱离了令人发指工作,一者是年底了,一者是不要向生活低头,就在这时我选择了第二者. 上家是做物联网的,人数不多,七八名开发人员,感觉都还可以,都很年轻没有秃顶,糊里糊涂就选择了入职. ...
- 易初大数据 2019年10月20日 spss习题 王庆超
一.选择题 1.有关spss数据字典的说法,正确的是:D A.SPSS数据集的数据字典可以复制到其他数据集中 B.SPSS数据集的数据字典是不能复制的 C.SPSS的数据字典可以通过“复制”和“黏贴” ...
- SVN--服务端安装和设置---centos7
一.安装环境 [root@localhost ~]# getenforce Disabled [root@localhost ~]# systemctl disable firewalld 二.yum ...
- 读《MySQL必知必会》我学到了什么?
前言 最近在写项目的时候发现自己的SQL基本功有些薄弱,遂上知乎查询MYSQL关键字,期望得到某些高赞答案的指点,于是乎发现了 https://www.zhihu.com/question/34840 ...
- Springboot 自动配置浅析
Introduction 我们知道,SpringBoot之所以强大,就是因为他提供了各种默认的配置,可以让我们在集成各个组件的时候从各种各样的配置文件中解放出来. 拿一个最普通的 web 项目举例.我 ...
- maven打包记录1
在需要打包的项目目录下找到pom.xml文件 (过程中可能遇到 :-Dmaven.multiModuleProjectDirectory system property is not set. Che ...