linux网易云教学视频,网易云课堂linux内核分析(一)

这是网易云课堂linux内核分析课程的实验报告

实验的内容是通过编写一段简单的c程序,并分析其汇编代码,以了解计算机是如何运行程序。

程序hello.c源代码:

1 #include

2

3 int bar(int a)

4 {

5 return a;

6 }

7

8 int foo(a)

9 {

10 return bar(a) + 1;

11 }

12

13 int main()

14 {

15 return foo(10) + 1;

16 }

在bash下输入如下指令,获得源代码的汇编hello.s:

gcc -S -o hello.s hello.c -m32

由于本次试验只需要用到源代码对应的汇编指令,所以可以把hello.s中以.开头的行删除。在vim下可以使用:

:%s/\s*\..*//g #将以"."开头的行换为空行

:%g/^$/d #删除空行

操作后得到以下代码:

1 bar:

2 pushl %ebp

3 movl %esp, %ebp

4 movl 8(%ebp), %eax

5 popl %ebp

6 ret

7 foo:

8 pushl %ebp

9 movl %esp, %ebp

10 subl $4, %esp

11 movl 8(%ebp), %eax

12 movl %eax, (%esp)

13 call bar

14 addl $1, %eax

15 leave

16 ret

17 main:

18 pushl %ebp

19 movl %esp, %ebp

20 subl $4, %esp

21 movl $10, (%esp)

22 call foo

23 addl $1, %eax

24 leave

25 ret

下面对汇编代码进行分析,从main函数开始:

18、19行的pushl和movl指令相当于enter指令,用于保存前一个栈的信息,同时为main函数开辟一个空栈。pushl将前一个栈的基地址保存,movl将ebp赋值为前一个栈的栈顶,同时也是main栈的基地址。esp作为main栈的栈顶。完成了上面两部,main栈就算建成了。接下来开始执行源代码里的东西了。

20、21行。subl为函数的栈开了空间,用来存放foo需要的参数。movl将参数放在该空间。然后执行call指令,跳到foo函数中,也就是eip要变成foo的地址。注意call指令要把当前eip压栈(pushl %eip)。然后把目光转到foo函数中,也就是第7行。和main函数开头一样,需要保存上一个栈的信息,同时为自己开创一个栈。pushl和movl指令做了这件事。接着放置bar需要的参数在自己的栈中(就是刚刚在mian函数时放的那个参数)。完成后执行call指令跳到bar函数。

bar函数终于不再调用别的函数,而是获取foo给的参数(第4行,这时候ebp就是foo栈的栈顶)。将参数赋值给eax后进行结束函数的工作。第5行的popl指令将esp加4,变为前一个栈(foo)的栈顶;ebp获得出栈的内容,也就是前一个栈的基址。foo的栈完成恢复。最后ret指令跳回foo函数中(相当于popl %eip),bar函数就正式结束了。回到foo函数后,根据源代码要给返回值加1(14行),紧接着要结束foo。和结束bar函数过程一样,结束foo函数就是执行leave然后回跳到main中。main函数为返回值加1(23行),以同样的流程退出main函数。程序结束。

注意1:函数的栈在内存中是从高地址向低地址增长的,所以pushl后esp要减4,而popl后esp要加4

注意2:leave指令相当于movl %esp %ebp,popl %ebp。

由于bar的代码没有使用到变量,所以在创建好函数的栈后,esp和ebp是相等的,不需要leave指令。函数foo和main中创建了变量,并存放在栈中,修改了esp,因此退出函数时要还原esp的。所以在退出函数的时候要使用leave。

注意3:call指令压栈的内容在调用函数的栈中。毕竟call指令执行在开辟新的函数栈指令之前。

理解:

程序就是由一条条汇编代码组成。这些汇编代码执行了运算,使用了内存空间。c语言中的函数,就是汇编中将当前寄存器保存到内存中,然后转跳到另外一处执行,执行完成后跳回原来地方,并恢复寄存器内容。而c语言屏蔽了这一过程,提供了抽象,我们只需要专注于函数要实现什么功能,不需要关注如何实现函数。

过程截图

bVsVQG

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值