linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作
标签(空格分隔): 20135321余佳源
一、实验
使用gcc –S –o main.s main.c -m32
命令编译成汇编代码,如下代码中的数字请自行修改以防与他人雷同
int g(int x)
{
return x + 3;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(8) + 1;
}
修改过后源代码:
对应的经过编译的对应汇编代码:
经过简化的汇编代码:
g:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl $53, %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 $2, (%esp)
call f
addl $1, %eax
leave
ret
堆栈变化图:
对应的寄存器指针内容变化状态图:
余佳源 原创作品转载请注明出处 《Linux内核分析》 MOOC课程 http://mooc.study.163.com/course/USTC-1000029000
对计算机的理解
计算机能实现许多看起来很复杂的功能,计算和处理大量的数据,但是,它实现这些复杂功能是不断地重复大量既定的简单的操作。目前大多数拥有计算和存储功能的设备(智能手机、平板、计算机等)其核心构造均为冯诺依曼体系结构,它最核心的思想是存储程序计算机,要点是:数字计算机的数制采用二进制;计算机应该按照程序顺序执行。
在过往的学习中我了解到,汇编语言是一种机器语言,通过对堆栈,对存储器,对寄存器,等等的操作,来实现一系列的指令。我们日常所使用的诸如c语言这种高级语言,落到具体操作的时候,在计算机的层面,还是依靠汇编语言来执行的。
通过以上一个小例子,清楚地展示了计算机是如何在堆栈中进行数据流的变化的。我的理解是,当开始运行一段程序,都是在往堆栈压入数据,这个例子中main函数代码运行过程就是这样,这一段代码中还嵌套了g、f函数,当这两个函数运行完成后,执行ret指令,堆栈中的值就开始出栈,当main函数也执行到ret,leave之后,一切都归回原位。小程序是这样的过程,大程序也如此。
学习汇编语言真正用的时候并不多,但它是我们分析处理问题的一种角度。能够看懂汇编语句,在分析程序真正执行的流程、单步调试程序的方面都是有帮助的。