2017-2018-1 20179215《Linux内核原理与分析》第二周作业
2024-09-25 05:18:37
20179215《Linux内核原理与分析》第二周作业
这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型、X86汇编指令包括几种内存地址的寻址方式和push、pop、call、re等几个重要的汇编指令。主要分为两部分进行这周的学习总结。第一部分对学习内容进行总结,第二部分对实验进行分析(反汇编一个C程序)。
一、学习内容
1、现在计算机绝大多数采用冯诺依曼体系结构,逻辑上可以抽象成:
以程序员的角度看:
2、几种寻址方式
• movl %eax,%edx edx=eax 寄存器寻址
• movl $0x123,%edx edx=0x123 立即寻址
• movl 0x123,%edx edx=*(int32_t)0x123 直接寻址
• movl (%ebx),%edx edx=(int32_t)ebx 间接寻址
• movl 4(%ebx),%edx edx=(int32_t)(ebx+4) 变址寻址
其中%..代表寄存器,$..代表取出数据,(%..)代表取出寄存器中所存储的数据,b、w、l、q分别代表8位、16位、32位和64位。
3、push、pop、call等几个重要的汇编指令。
eg (1) pushl %eax 意思是把eax寄存器压栈。分解来看相当于第一步:subl $4 esp,第二步:movl %eax (%esp),来解释一下:首先我们要知道esp是指堆栈栈顶,那么由于栈的一般生长方向为自上向下增长,进行push压栈指令时栈顶指针向下移动4个字节(因为是32位机),之后把eax放入当前内存位置。
(2) popl %eax意思是把eax寄存器出栈。分解来看相当于第一步: movl(%esp), %eax第二步:add $4 %esp,道理同(1)逆。
(3) call 0X12345 意思是函数调用,过程是首先将当前CPU获取内存的指令压栈保存,赋予新值,CPU下次就从新地址来取指令了,即实现了函数调用。
二、实验分析
首先创建main.c文件,即:touch main.c,之后用如下命令输入一段C语言代码:
$vi main.c,之后用gedit main.c 查看编写好的C程序,如下图所示:
然后用如下命令反汇编:$gcc -S -o main.s main.c -m32,之后用gedit main.c 查看结果,如下图所示:
由于“.”开头的大都是用于链接辅助信息,实际并不会执行,所以可以直接忽略。删除所有点开头的内容,留下来的是纯汇编代码。那么此段程序简化后就变成如下形式:
g:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl $20, %eax
popl %ebp
ret
f:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call g
leave
ret
main:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl $10, (%esp)
call f
addl $30, %eax
分析如下图:
Eip寄存器 从这条指令执行完自动执行下有一条指令
Ebp寄存器 总是指向堆栈的栈底 概念的是相对的,跳出该函数进入其他函数堆栈有其相应的栈底
Esp寄存器 总是指向堆栈的栈顶
Eax寄存器 函数的返回值默认使用该寄存器存储返回给上一级函数
分析如下:
程序从main函数开始运行,因为之前还有别的代码运行,所以把当前ebp进行压栈,之后指针向下一个字节,相当于在下个字节内填充数据,之后调用f函数,而当前eip指向call f的下一条指令(eip在进行call f指令后压栈,下回跳转到eip继续执行)。那么对于即将要执行的f函数来说首先要将当前ebp压栈,那么和main函数类似,指针下移一个字节,把10放进寄存器eax中,再把寄存器eax给esp,当前eip指向call g的下一条指令(当前eip在进行call g指令后压栈),之后调用g函数,同样先将ebp压栈,之后esp,ebp指向同一个位置,之后ebp指针向上移动两个字节把当前字节内内容放到eax寄存器中,将eax储存的数加20后出栈,返回到f函数的leave命令,撤销函数堆栈后返回到main函数的leave命令,将eax的当前值30加30,之后撤销函数堆栈,返回程序运行值。
最新文章
- JS数组操作示意图(shift,unshift,pop,push)
- MVVM架构~knockoutjs系列之从Knockout.Validation.js源码中学习它的用法
- Linux上服务的启动,停止和重启
- 多台web如何共享session进行存储(转载)
- JDK,JRE,JVM区别与联系
- 【转载】linux strace
- Http请求头中的字段理解
- 1_3 C语言解决求n!
- Unity 三角函数 向量 运算
- Eclipse使用过程中的经验总结
- python第四章:函数--小白博客
- 减少MySQL主从延迟的神器--并行复制大揭密
- 树莓派中编译Opencv3.4.1和OpenCVSharp库
- 戴尔poweredge r730服务器配置以及系统安装
- mongodb及mongoclient在win7下的编译和使用
- 爬虫_处理js动态加载
- 6-17 Shortest Path [2](25 分)
- python3用pillow生成验证码,tornado中输出图片
- Delphi 中调用JS文件中的方法
- lesson 20 pioneer pilots
热门文章
- 1、Codevs 必做:2833、1002、1003、2627、2599
- GitHub 小试牛刀(踩坑记录)
- 【BZOJ4927】第一题 双指针+DP(容斥?)
- Count(二维树状数组)
- XmlDocument.selectNodes() and selectSingleNode()的xpath的学习资料
- URAL 1181 Cutting a Painted Polygon【递归+分治】
- mydql练习答案
- 我的Android进阶之旅------>MIME类型大全
- kettle连接资源库设置
- Ubuntu 13.04 可以使用的源