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,之后撤销函数堆栈,返回程序运行值。

最新文章

  1. JS数组操作示意图(shift,unshift,pop,push)
  2. MVVM架构~knockoutjs系列之从Knockout.Validation.js源码中学习它的用法
  3. Linux上服务的启动,停止和重启
  4. 多台web如何共享session进行存储(转载)
  5. JDK,JRE,JVM区别与联系
  6. 【转载】linux strace
  7. Http请求头中的字段理解
  8. 1_3 C语言解决求n!
  9. Unity 三角函数 向量 运算
  10. Eclipse使用过程中的经验总结
  11. python第四章:函数--小白博客
  12. 减少MySQL主从延迟的神器--并行复制大揭密
  13. 树莓派中编译Opencv3.4.1和OpenCVSharp库
  14. 戴尔poweredge r730服务器配置以及系统安装
  15. mongodb及mongoclient在win7下的编译和使用
  16. 爬虫_处理js动态加载
  17. 6-17 Shortest Path [2](25 分)
  18. python3用pillow生成验证码,tornado中输出图片
  19. Delphi 中调用JS文件中的方法
  20. lesson 20 pioneer pilots

热门文章

  1. 1、Codevs 必做:2833、1002、1003、2627、2599
  2. GitHub 小试牛刀(踩坑记录)
  3. 【BZOJ4927】第一题 双指针+DP(容斥?)
  4. Count(二维树状数组)
  5. XmlDocument.selectNodes() and selectSingleNode()的xpath的学习资料
  6. URAL 1181 Cutting a Painted Polygon【递归+分治】
  7. mydql练习答案
  8. 我的Android进阶之旅------>MIME类型大全
  9. kettle连接资源库设置
  10. Ubuntu 13.04 可以使用的源