[[420603]]
计算机如何执行你写的代码?
知乎上有人提问:电脑怎样执行编程语言的?
很多刚刚入坑的小白可能对此完全没有概念,或者模模糊糊知道个大概,一行代码我们写下的揭开一行行代码,计算机到底是行原如何在执行的呢?
我们以x86架构的CPU为研究对象,从一个例子出发,一行代码来尝试解答这个问题。揭开
为了方便编程,一行代码伟大的揭开计算机先驱们发明了一个又一个的编程语言,使得我们可以用人类最容易理解的行原语法规则去告诉计算机完成我们想要的功能。
比如,一个C语言程序员写下了一行代码:
- int sum = a + b;
一句简单的不能再简单的C语言语句。
但即便是如此简单,聪明绝顶的计算机却还是看不懂:这是弄啥捏?
这时候就需要一个翻译,负责把人类编写的高级语言“翻译”成计算机能看得懂的东西,这个翻译就是编译器。
上面的高级语言语句经过编译器编译链接后,生成了一个目标运行平台为x86架构的可执行程序exe/elf,使用反编译工具IDA进行分析,可以看到这行代码编译后的样子是这样的:
mov eax, a : 将变量a的值存入eax寄存器中
add eax, b : 把变量b的值和eax寄存器的值相加,并将结果保存在eax寄存器中
mov sum, eax : 将计算结果从eax寄存器写入sum变量
看到了吗,就像把大象关进冰箱需要分三步,计算机完成程序员的一条加法语句,也分了三步:取出被加数、加上加数、写入结果。
上面的汇编指令只是为了人类理解方便的助记符,计算机同样也不认识这玩意,那几条指令在内存中实际上是这样的一串数据:
十六进制:
- 8B 45 EC 03 45 E0 89 45 F8
十六进制是为了书写方便,计算机真正能看到的只有二进制的比特流:
- 10001011 01000101 11101100 00000011 01000101 11100000 10001001 01000101 11111000
接下来,计算机要做的事情就是识别这些二进制流都是什么意思,转换成一条条的指令来执行。
在开始执行之前,先来了解一下指令格式。
x86架构CPU指令集中的指令格式如下:
主要有六个部分:
需要注意的是,并不是每一条指令都包含上面的所有部分,许多指令只包含其中一部分字段。
根据操作码的长度不同,指令分为单字节操作码指令、双字节操作码指令、三字节操作码指令。
计算机中真正负责指令执行的核心部件是中央处理器CPU,在CPU中有一个指令寄存器IP,全称是Instruction Pointer,在32位下,它叫EIP,在64位下它叫RIP。
下面开始执行:
指令寄存器EIP指向了第一条指令,开始读取第一个字节:10001011,也就是0x8B。
开始指令译码,翻译出这是一条什么指令。
下面是x86架构的CPU指令操作码表:
CPU中的指令译码模块拿到手一看,呀,不是指令前缀,是个单字节操作码的mov指令,要往eax寄存器里面塞数据,数据从哪来呢?
再往后一看,0x45,再来译码:
好家伙,原来是根据ebp寄存器的值+一个8位的偏移来读取数据。
再往后读取一个字节,就是偏移值:EC。
现在第一条指令就译码出来了:将ebp+0xEC位置处的4个字节的数据取出来,放到eax寄存器中。,这就是这一条指令要干的事情。
同时CPU还得出了另一个信息:这一条指令长度是3个字节,下一条指令的起始地址是在3个字节之后,随后,指令寄存器EIP向后拨动,指向下一条指令的地址:$+3。
指令译码完成之后,开始来正式执行它。
执行完一条以后,又来到指令寄存器EIP指向的地方,随后再次指令译码、执行,不断重复这个过程,依次执行每一条指令。
这其实就是CPU工作最基本的原理。
上面描述的过程是CPU在硬件电路层面完成的,但这种设计思想在软件领域也同样适用。
大家如果去研究Java虚拟机JVM和Python的解释器源代码时,也会发现有相似之处:JVM和解释器通过定义一套自己的“指令集”,然后它们的编译器使用这套指令集将Java和Python代码编译成对应的程序。
运行的时候也类似,虚拟机或者解释器不断识别每一条指令,译码、执行,和CPU执行指令的过程颇有几分相似。
C/C++语言编译的程序,最后是直接编译成了CPU的指令,所以跨平台能力差,如果换到ARM架构平台,原来的程序将无法执行,需要重新编译成新的平台的程序。
而Java、Python这类语言,是自己在软件层面的指令集,因为其自身已经开发了针对不同CPU平台的虚拟机、解释器,所以这些语言编写的程序移植性好,真正做到一次编写,到处运行。
我们使用高级语言C、C++编写的程序代码,经过编译器的编译链接,最终变成CPU可以理解的机器指令,随后CPU在执行时通过不断的译码、执行,最终实现高级语言所描述的功能。
现在你知道你用编程语言写下的程序是如何跑起来的了吗?
责任编辑:武晓燕 来源: 编程技术宇宙 CPU执行语言(责任编辑:综合)
赛生药业(06600.HK)年度实现纯利7.5亿元 每股基本盈利约为人民币1.38元
英伟达否认放弃收购Arm股价收盘大跌4.5% 公司回应态度不变
去年全国规模以上工业增加值同比增加9.6% 工业经济平稳运行底气足
成自高铁白云山隧道顺利贯通 为实现2023年底全线通车按下“加速键”
齐家控股(08395.HK)发布公告:中期纯利同比减少29.1%
抓住RCEP发展机遇!商务部等6部门重磅发文 促进经济高质量发展
荣盛发展大股东质押公司7599万股股份 占公司总股本比例的1.75%
颐海国际(01579.HK)获瑞银增持44.33万股 每股均价25.4245港元