代码运行过程详解---重中之重

目录

运行模型

代码段

数据段

关键点


运行模型

指令指针从下向上拨动

栈底指针从上到下拨动

CPU在执行指令的时候,也会操作内存

代码段

  • 编译器把C语言代码编译成二进制的指令代码
  • 程序运行的时候把二进制代码加载到代码段
  • 代码段只读,不能被修改   ------>   安全
  • CPU有一个指令指针,指向当前执行的指令
  • CPU执行完一条指令后,在移动指令指针到下一个位置
  • 指令条件跳转
    int a = 3; // 局部变量都是定义在栈上的

    if (a > 0) {
        printf("if a > 0");
    }

    else {
        printf("else called");
    }
  • 指令循环跳转
    int i = 0;

    while (i < 10) {
        i++;
    }
  • 函数调用跳转, 函数返回跳转, 参数传递
    int test_func(int a, int b) {

       int c;

       c = a + b;
       return c;
    }

    int main(int argc, char** argv) {

       int a = 3;
       int b = 4;
       int c = 0;

       c = test_func(a, b);
       system("pause");

       return 0;
    }

数据段

  • 每个进程运行程序的时候都会分配一个数据段
  • 数据段存放这个程序中所有的全局变量并为它分配好内存
  • 内存一旦分配好,再也不能增加也不能减少

  • 操作系统会为每个进程分配一个栈
  • 栈的大小有限,而且大小不大,所以不要在栈上分配大规模的内存块
  • 栈底指针是往下拨动,内存就分配出来,往上拨动,内存回收
  • 局部变量与函数的参数内存都分配在栈上   ------>   函数参数分配内存,按照从右到左的顺序

关键点

  • 分配局部变量与参数   ------>   栈指针往下拨动变量所底需的大小分配出来

  • 程序运行时的栈大小是有限的   ------>   不要定义大块内存的局部变量

  • 函数调用

  1. 分配我们的参数的内存,从参数的右边到左边   
  2. 将参数对应的内存做好数据初始化      
  3.  将我们的下一条指令的位置,保存在栈里面      
  4. 保存一下,我们栈底在调用函数之前的位置     
  5.  把指令指针拨动到调用函数的地方
  • 函数返回   ------>   那怕没有返回值,也会有一个隐式的   return

  1. 回收这个函数里面的局部变量,将我们的栈底拨回到我们没有调用函数前的地方   
  2.  将我们的指令指针,拨回我们保存的下一条语句要执行的地方     
  3. 保存我们的返回值,到一个地方   ------>   VS是在EAX寄存器 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值