这一切都始于 CPU 或处理器。每种处理器类型都有一组定义的能够执行的指令。这些指令对 1 和 0 进行操作,而这些指令又代表您希望它们执行的任何操作:数字、字母,甚至指令本身。
在最低级别,零是由晶体管上存在的特定电压(通常接近 0V)确定的,而 1 是存在不同的电压(取决于 CPU,例如 5V)
机器指令本身是一组零和一,放置在处理器中称为寄存器的特殊位置,处理器从特定位置获取指令及其操作数并执行操作,将结果放置在另一个位置,然后再获取下一条指令等等,直到它用完要执行的指令或被关闭。
一个简单的例子。假设机器指令 001 表示两个数字相加。
然后编写一个将两个数字相加的程序,通常如下所示:
4 + 5
然后,您将此文本传递给编译器,该编译器将为您将运行该程序的处理器生成足够的机器代码(旁注,您可以编译代码以在与当前正在运行的处理器不同的处理器中运行,这是一个名为交叉编译,它很有用,例如,在嵌入式平台中)。好吧,编译器最终会大致生成,
001 00000100 00000101
使用额外的样板机器代码将 001 指令放置在下一个指令寄存器(指令指针)中,并将二进制编码数放置在数据寄存器(或 RAM)中。
从结构化语言生成机器代码的过程相当复杂,并且限制了这些语言最终的正常程度。这就是为什么你不能用英语编写程序,其中有太多歧义,编译器无法生成正确的零和一序列。
CPU 可以执行的指令相当基本和简单,加法、除法、求反、从 RAM 读取、放入 RAM、从寄存器读取等等。
下一个问题是,这些简单的数字指令如何产生我们在计算(互联网、游戏、电影播放器等)中看到的所有奇迹?
它基本上可以归结为创建足够的模型,例如 3D 游戏引擎有一个代表游戏世界的数学模型,并可以基于它计算游戏对象的位置/碰撞。
这些模型是基于许多这样的小指令构建的,这就是高级语言(不是机器代码)真正发挥作用的地方,因为它们提高了抽象级别,然后您可以更接近您想要实现的模型,让你可以轻松地推理出诸如如何根据从控制器接收到的输入有效地计算士兵将要到达的下一个位置之类的事情,而不是因为你太忙于不忘记 0 而妨碍你轻松推理。
一个关键时刻发生在从汇编语言(一种与机器代码非常相似的语言,它是第一种编程语言,并且它是特定于 CPU 的。每条汇编指令都直接翻译成机器代码)到 C(可在不同 CPU 之间移植,并且是比汇编更高的抽象级别:每行 C 代码代表许多机器代码指令)。这对于程序员来说是生产力的巨大提升,他们不再需要在不同的 CPU 之间移植程序,并且可以更轻松地思考底层模型,从而导致我们所看到的软件复杂性持续增加(甚至是需求)从 20 世纪 70 年代至今。
悬而未决的缺失环节是如何控制如何处理该信息以及如何接收来自外部源的输入,例如在屏幕上显示图像或将信息写入硬盘驱动器,或在打印机上打印图像,或从外部接收击键。键盘。这一切都是通过计算机中存在的其余硬件实现的,这些硬件以类似于 CPU 的方式进行控制,您将数据和指令放置在图形卡或网卡或硬盘驱动器或计算机中的某些晶体管中。内存。 CPU 具有的指令允许其将某些数据或指令放入(或从中读取信息)不同硬件的正确位置。
与我们今天所拥有的存在相关的另一个事情是,所有现代计算机都带有称为操作系统的大型程序,它管理所有基本的东西,例如与硬件通信和错误处理,例如程序崩溃时会发生什么等等。此外,许多现代编程环境都附带a lot已编写的代码(标准库)来处理许多基本任务,例如在屏幕上绘图或读取文件。该库将依次要求操作系统代表其与硬件进行对话。
如果这些不可用,编程将是一项非常非常困难和乏味的任务,因为您编写的每个程序都必须再次创建代码以在屏幕上绘制单个字母或从每种特定类型的硬盘驱动器读取单个位,例如。
看来我得意忘形了,我希望你能从中理解一些:-)