您的位置:首页 > 理论基础

linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作

2016-02-27 19:45 661 查看
一、实验

使用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    $4, %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    $3, %eax
leave
ret


堆栈变化图:





在汇编代码中分析堆栈变化:

g:
pushl    %ebp      ;ebp4入栈 ebp指向4 esp指向7
movl    %esp, %ebp   ;ebp = esp =7
movl    8(%ebp) ,%eax ;eax = 2
addl    $4, %eax ;eax + 4 = 6

popl    %ebp ;ebp出栈 ebp指向esp1 esp减4
ret  ;ret = pop eip eip14出栈 esp指向5
f:
pushl    %ebp ;ebp1入栈 ebp指向1 esp指向4
movl    %esp, %ebp ;ebp = esp =4
subl    $4, %esp ;esp -4 指向5
movl    8(%ebp), %eax ;ebp+8=eax 指向2 eax = 2
movl    %eax, (%esp) ;把eax放入esp所指的位置
call    g ;调用g函数 eip15入栈
leave   ;leave = movl %ebp %esp popl %ebp esp = ebp = 4 ebp1出栈 ebp指向1 esp-4指向3
ret   ;eip23出栈 esp-4指向2
main:
pushl    %ebp ;ebp0入栈 ebp指向0 esp指向1
movl    %esp, %ebp ;ebp = esp =1
subl    $4, %esp ; esp-4 esp指向2
movl    $2, (%esp) ;2入栈
call    f ;调用f函数 push eip movl eip eip23入栈
addl    $3, %eax ;eax+3
leave ; esp = ebp = 1 esp0出栈 ebp = 0 ebp-4 = 0
ret


总结:

  通过这个小实验,可以清楚地认识冯.诺依曼体系,也就是计算机工作的过程,通过各种的寄存器存放数据或指令,系统在通过指令一步一步向下执行。从这个堆栈的分析可以看出系统先将main函数压入栈中,调用f函数时将f函数压入栈中,调用g函数同样如此;在g函数使用完毕后,释放g函数所占用的堆栈,继续执行未执行完的函数命令,直到程序运行完毕或者出错。也就是说计算机工作就像是流水线一步一步取指译码执行。

郭皓原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐