zoukankan      html  css  js  c++  java
  • 计算机是怎样工作的函数调用堆栈机制

    简介:解释单任务计算机(不考虑中断)的函数调用堆栈机制,并在此基础上讨论分析多任务计算机是怎样工作的

    实验过程:

    从c源代码到运行可执行程序一般要经过以下几个阶段:

    预处理->编译->汇编->链接

    源程序:example.c 

    int g(int x){
        return x+3;
    }
    
    int f(int x){
        return g(x);
    }
    
    int main(void){
        return f(8)+1;
    }

     1.预处理:将c源文件预处理生成example.cpp文件

     2.编译:将预处理好的example.cpp文件编译生成example.s汇编代码 

    3.汇编:将汇编代码example.s文件编译为目标文件example.o

    4.链接:将目标文件example.o与所需的所有附加的目标文件连接起来,生成可执行文件example(本实验未包含静态和动态链接库这样的附加的目标文件)

     实验分析:

    查看example.s文件,分析main()函数的执行过程:

      伪代码:

    g:
    .LFB0:    
        pushl    %ebp    
        movl    %esp, %ebp    
        movl    8(%ebp), %eax
        addl    $3, %eax
        popl    %ebp    
        ret
    
    f:
    .LFB1:    
        pushl    %ebp    
        movl    %esp, %ebp
        subl    $4, %esp
        movl    8(%ebp), %eax
        movl    %eax, (%esp)
        call    g
        leave    
        ret
    
    
    main:
    .LFB2:    
        pushl    %ebp    
        movl    %esp, %ebp    
        subl    $4, %esp
        movl    $8, (%esp)
        call    f
        addl    $1, %eax
        leave    
        ret
        

    在main函数段的部分,首先构造堆栈框架

     pushl    %ebp    
     movl    %esp, %ebp 

                            堆栈变化


     接着将要调用的函数参数压栈

    subl    $4, %esp
    movl    $8, (%esp)

            堆栈变化


     然后调用函数f()

    	call	f
    

     

            堆栈的变化    

     

                             程序代码段的变化


    f()函数段部分,类似的构建堆栈

    pushl    %ebp     
    movl
    %esp, %ebp subl $4, %esp

                        堆栈变化


     接着,将参数8存入寄存器eax,并将该值存入esp所指向的内存单元

    movl    8(%ebp), %eax
    movl    %eax, (%esp)

          堆栈变化


    然后调用g()函数

    	call	g
    

         

                堆栈变化                   程序代码段变化


    函数g()部分,类似的构造堆栈,将参数8存储到eax,执行加3运算后在存入eax作为函数的返回值,最后将ebp出栈,返回到f()

    pushl    %ebp    
    movl    %esp, %ebp    
    movl    8(%ebp), %eax
    addl    $3, %eax
    popl %ebp
    ret

    堆栈变化:      构造堆栈                  ebp出栈                  执行ret 弹出地址

      

        程序代码段变化


    返回到f()段后,执行将栈返回并返回main()函数

    leave    
    ret

                

    堆栈变化: 执行leave后            执行ret后                    程序代码段变化


     回到main()函数段后,执行将eax中的值11执行加1运算后存入eax作为main()函数的返回值,接着将栈返回并退出

          堆栈返回

    实验总结:

      对于单任务计算机,通过eip找到程序代码段顺序执行每一条指令,当遇到控制语句(如跳转指令jmp)以及过程调用(如本实验中的call g)时会改变eip的值,使eip跳转到不同的位置继续顺序的执行程序代码段的每一条指令。不同的函数具有不同的栈空间,当执行有关堆栈操作的指令时(如本实验中的push等),相应函数的堆栈会发生相应的变化。

      对于多任务计算机,通常利用时间片轮转的机制,系统的调度进程转依次调度执行就绪队列中进程。每个进程都有自己独立的进程空间,所以在进程切换时,会首先进行进程上下文切换,接着就如同单任务计算机一样执行当前的进程

     

      

  • 相关阅读:
    选择排序
    插入排序
    冒泡排序
    java实现串的匹配和替换
    动态字符串的存储结构的实现
    静态串的存储结构以及增删改查
    链式队列的操作实现
    java中程序的执行的原理如怎么创建空间,创建对象等
    java中的环境变量的配置
    java的JVM以及java中代码的运行过程
  • 原文地址:https://www.cnblogs.com/wenxuanguan/p/3082686.html
Copyright © 2011-2022 走看看