暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

CPU如何运行你的HelloWorld?

go技术沙龙 2021-02-24
359

你真的了解你编写的java,go程序是如何在cpu中运行的么? 通过 javac,go build编译后的程序CPU又是怎么解释执行的呢?

源代码--->javac编译--->字节码文件--->Jvm--->解释成机器码--->CPU解释执行

CPU如何解释执行的呢?

CPU组成

  • 寄存器

    • 用来暂存指令,数据等

  • 控制器

    • 负责把内存上的指令,数据读入寄存器

  • 运算器

    • 负责运算读入寄存器中的数据

  • 时钟

    • 用于中断

内存

  • 主存

    • 计算机内部,负责存储程序,数据等的装置

寄存器

  • 累加寄存器 (1个)

    • 存储用于运算的数值

  • 基址寄存器/变址寄存器 (n个)

    • 用于存储表示内存地址的数据

  • 程序计数器 (1个)

    • 存储下一条指令所在的内存地址

    • 决定程序的运行流程

  • 标志寄存器 (n个)

    • 存储运算后的CPU的状态

  • 通用寄存器 (n个)

    • 存储任意数据

  • 指令寄存器 (1个)

    • 存储指令,CPU内部使用,程序员无法通过程序对该寄存器读写操作

  • 栈寄存器 (1个)

    • 存储栈区域的起始地址

决定程序运行流程-程序计数器

  • 顺序执行

  • 条件执行/循环执行

    此处 指令“大于0则跳转到0104地址”,间接执行了“将程序计数器设定为0104地址”这个操作。在循环中也是根据机器指令(jump)跳转指令完成执行顺序的调整,同时这里运用CPU中的标志寄存器存储累加寄存器的运算结果是负数,零还是正数。比较运算的结果存储到标志寄存器中。

    程序中的比较指令,其实就是在CPU内部做减法运算。

函数的调用机制

  • 函数的调用处理也是通过把程序计数器的值设置成函数的存储地址来实现的

  • 函数调用时参数的传递可以通过寄存器和内存完成

  • 不过函数调用和if-else,循环不同之处在于,函数调用后,要返回到函数调用的原点继续往下执行

  • 如果这里也使用之前的机器指令(jump),那么在函数执行完之后则没有办法返回到函数的执行原点继续往下执行

  • 如果要想让函数执行后返回函数调用的原点则可以使用机器指令 call 和 return 来完成。

1,call指令会把要跳转的函数地址设定到程序计数器中,同时会把函数调用后要执行的指令地址存储在名为栈的主内存中。

 

2,return指令则在函数执行完毕后把栈中的指令地址设定到程序计数器中

 

数组的实现

使用基址寄存器和变址寄存器可以实现高级语言中数组。

基址寄存器存储数组的起始地址,变址寄存器则用于存储整个连续地址的变化。

 

CPU可以执行的机器语言指令

  • 数据转送指令

    • 寄存器和内存,内存和内存,寄存器和外围设备之间的数据读写操作

  • 运算指令

    • 用累加寄存器执行算术运算,逻辑运算,比较运算和移位运算

  • 跳转指令jump

    • 实现条件分支,循环,强制跳转

  • call/return指令

    • 函数的调用/返回调用前的地址

总结

通过以上概念的介绍是不是对于CPU的运行原理有了大体上的了解,其实不管是操作系统,用户程序最终都会被转义成CPU可以解释运行的机器码。

  • C,java编写的程序转换成机器码

  • CPU通过控制器把一条指令,数据加载到寄存器,

  • 同时程序计数器中保存下一条要加载的指令地址

  • 运算器通过机器指令(Add,Move,Jump,Call,Return...)完成数据的计算

  • 指令寄存器存储CPU运算过程中一些状态的保存

  • 如果涉及到函数调用,参数传递通过主存(栈)传递

  • 控制器处理计算后的结果(写回内存),计算后的结果存储在CPU寄存器中


文章转载自go技术沙龙,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论