编程语言和操作系统是什么关系?编程语言如何被计算机执行的?驱动程序的理解?

编程语言和操作系统是什么关系?

首先,编程语言是不能运行的,它是可运行的计算机程序的一种表达方式,而编译器或者解释器把编程语言转换为计算机可执行的程序。

而操作系统也是一种可执行的计算机程序,它通常先在计算机上运行起来,作为一套中间层存在。我们都知道,中间层是为了提供抽象转换而存在的,而这套叫做操作系统的中间层,定义了一套规则,使得后续的可执行程序能够更容易的被运行起来,而且能更容易的利用各种硬件(显示,键盘等等),能够调用一些库来消除不同的程序间重复的运行逻辑。

总结下,编程语言是一种可执行程序的表达方式,编译器把编程语言的表达方式转换为可执行的程序,而编译器做转换的过程,可以操作系统相关(也就是转换出的程序运行在特定操作系统上),也可以操作系统无关(直接在裸机运行)。而操作系统,本身是一个程序,也可以是编程语言来表达的(编译后通常操作系统无关),也可以不是(直接写机器码),而操作系统这个特殊的程序,提供了库,硬件驱动,运行时环境,框架等,是为了让运行在其上的程序写得更容易

编程语言实际如何被计算机执行的

以c语言中的printf举例,如printf的底层就是调用了系统调用write函数,write系统调用函数作为操作系统API,为用户层提供写文件最基本的实现。这里系统调用write函数(write是属于c语言函数)的底层实现就是系统调用指令(汇编)的封装,注意系统调用的过程是在内核空间执行的,而write只是封装的一个c库函数来触发系统调用。我们知道调用“系统调用”有两种方式。
( 1) 将系统调用指令封装为 c库函数,通过库函数进行系统调用,操作简单。
(2)不依赖任何库函数,直接通过汇编指令 int与操作系统通信,int是指中断。这一条总结下来就是不用库函数,直接进行系统调用。

所以通过printf函数的实际实现其实是汇编指令的这个例子,我们可以认为c语言的底层实现就是汇编指令,因为c语言在编译过程中也都会全被翻译成汇编。最后翻译好的汇编在编译链接的倒数第二步时会全部被翻译成机器指令,每条汇编指令都有一条对应的机器码,逐行翻译就行了。然后在执行时,cpu发出指令让这些程序从硬盘中加载进内存。(如何从磁盘被加载进内存的就不深究了,涉及到磁盘的读写等物理知识,总的来说就是通过数据总线这些玩意儿做的事情)

接下来就是计算机执行机器指令了。注意这里最后翻译得到的机器指令并不是指verilog语言!verilog虽然是机器语言,但是和机器指令是两个东西,机器指令就是0101的数字组合!而我们这是直接用已经被设计好的cpu(即verilog写好实现的逻辑电路)。计算机执行一个机器指令经历了这5个阶段,这5个阶段为什么能够被执行?是因为在设计cpu时,数据的流动及其过程就已经被实现了:

  1. 取指: 根据pc 的寄存器中存的指令的内存地址,取指指的是根据这个内存地址从内存中取出指令。
  2. 译码:把需要用到值从寄存器中取出来。
  3. 执行:接着把取出的数据按指令所要求的算法进行加工。执行时会根据机器指令里的信号(比如00)选择对应的电路结构来进行计算。
    算术逻辑单元
  4. 访存:执行后自然就会产生结果,结果呢当然需要存储起来,有的需要根据计算出的内存地址,从中取出数据,有的也需要把数据写入指定的内存地址。
  5. 写回:执行后的结果,以及访存后的结果可能需要写入到寄存器中。寄存器只是CPU结构内用来存储当前程序需要用到的一些数据,这些贮存在寄存器内的数据可以实现高速读写,减少了进程从存储器中读取数据的时间。只有一部分数据会存储在寄存器里,其他数据会在主存储器(内存)与外存储器(硬盘)中。

比如拿硬件描述语言Verilog举例,我们可以用Verilog设计一个cpu,当用Verilog代码描述出硬件功能后,我们需要用综合器对Verilog代码进行解释,将代码转化成实际的电路来表示,得到最终实际的电路,综合时也会考虑电路的输入输出。FPGA里的是逻辑组合门阵列,它给你准备了资源,你要用哪些资源就需要用Verilog去形成电路和调用。Verilog描述生成的电路是可以包含数据流动和不包含数据流动的。如果Verilog代码中指定了输入输出(输出输出可以是实际值,也可以是由外设传进来)就表示了电路中有数据流动。如果不指定输出输出,那么生成出来就是一个独立的逻辑门电路,实际并不会这样做,因为并没啥用处。再综合完后的下一个步骤就是布局布线了,布局布线中就是指定输入的管脚和输出的管脚(如果输入输出在Verilog中给了定值的话,就不需要为他们指定输入输出管脚了)。为什么形成的中间的逻辑门电路组合能保证和硬件适配呢?这是因为我们在写Verilog代码之前就需要指定板子的型号。再举个例子,我们现在电脑用的cpu,其实就可以看做用Verilog写好后并被综合了的FPGA逻辑门阵列。FPGA板子上的各个逻辑门之间本身就是联通的,只是没有供电。一通电后板子上所有模块都有电流了!verilog为什么能组合不同的逻辑门形成新的电路的原因是因为verilog代码经过烧写后会生成的对应的电信号,能控制信号的走向使得经过我们设计的逻辑门组合。程序的本质是产生电信号,这里应该指数字信号因为是0101(电信号的具体原理就和数电模电有关了)。这些电流信号控制着逻辑电路的关断,通过关闭逻辑电路来控制硬件的工作。
程序里0和1是怎么转化成高低电平的?
软件是如何做到控制芯片电路的闭合的?解释非常清晰!:当程序打开的时候,和这个程序相关的数据就会从硬盘中读取,传输到内存中。硬盘的磁头读取数据时,旁边的读取器可以识别磁性材料的不同极性,再还原成高电平和低电平,刚刚我们就提到了在芯片和电路中0和1是由高电平和低电平来表示。
FPGA的cpu的逻辑电路是固定好的,用的时候就是直接调用,是不可编程的,即不能实现任意逻辑电路的自由组合(注意这里是指“逻辑”!所以这些所有不同模块的电路即物理上的导线都是早就连通好焊死了的)FPGA可编程的原理

既然内存是用来存放当前正在使用的(即执行中)的数据和程序,那么它是怎么工作的呢?我们平常所提到的计算机的内存指的是动态内存(即DRAM),动态内存中所谓的“动态”,指的是当我们将数据写入DRAM后,经过一段时间,数据会丢失,因此需要一个额外设电路进行内存刷新操作。具体的工作过程是这样的:一个DRAM的存储单元存储的是0还是1取决于电容是否有电荷,有电荷代表1,无电荷代表0。但时间一长,代表1的电容会放电,代表0的电容会吸收电荷,这就是数据丢失的原因。刷新操作定期对电容进行检查,若电量大于满电量的1/2,则认为其代表1,并把电容充满电;若电量小于1/2,则认为其代表0,并把电容放电,藉此来保持数据的连续性。

驱动程序

驱动程序是什么:驱动程序与硬件相关,编写驱动程序要非常了解硬件,同时给应用层提供API函数接口,应用层可以调用这些接口去访问硬件而不必了解硬件。
如果有上层应用软件来控制硬件时,还可以这样理解:驱动程序就是衔接操作系统与外部的硬件的C代码。因为上层的应用软件最后都是会调用操作系统api去做事情的。那操作系统怎么和硬件做交互?答案就是通过驱动程序实现的。

通俗地解释:比如说你有一个应用是控制每天早上六点钟开灯.应用程序只负责在适当的时间做适当的事(到六点了,要开灯了,触发按键信号,这个信号由操作系统调度通过驱动程序相应的API接口下发至硬件);具体它不用知道为什么按下键就能开灯,因为按下键后开灯的事情就是驱动程序完成了,驱动程序再去控制硬件管脚发出高低电平信号去驱动灯的开关.

单片机驱动程序文件组成:以led点灯为例,包括三个文件led.h(包括宏定义,变量声明,函数声明),led.c(模块的具体代码实现),main.c(工程的主函数,调用模块函数并适当组合就可以完成工程的项目要求功能)三个文件。用keil编译

扫描二维码关注公众号,回复: 16562943 查看本文章

refer:
操作系统学习(二)–进程描述和执行
单片机驱动程序编写
OpenGL与显卡驱动
操作系统——系统调用
用户态和内核态的简单理解
底层原理——用户态和内核态的区别,和上面一篇结合起来看,非常重要!
调用"系统调用函数write"的两种实现
计算机机器语言是如何被执行的
chisel搭个cpu(二) SW功能(实现译码/执行/访存)
明德扬至简设计法–verilog综合器和仿真器

猜你喜欢

转载自blog.csdn.net/Rolandxxx/article/details/127834284