机器代码
机器代码是特定本机数据格式的术语,由机器直接处理 - 通常由称为 CPU (中央处理单元) 的处理器处理。
通用计算机体系结构( 冯诺依曼体系结构 )由通用处理器(CPU),通用存储器组成 - 存储程序(ROM / RAM)和处理数据以及输入和输出设备(I / O 设备)。
这种架构的主要优点是每个组件的相对简单性和通用性 - 与之前的计算机机器(机器结构中的硬连线程序)或竞争架构(例如哈佛架构将程序存储器与存储器的内存分开)相比数据)。缺点是总体性能稍差。从长远来看,普遍性允许灵活使用,这通常超过了性能成本。
这与机器代码有什么关系?
程序和数据作为数字存储在这些计算机中的内存中。没有真正的方法来区分数据代码,因此操作系统和机器运算符在将所有数字加载到内存后给出 CPU 提示,在该提示处,内存的入口点启动程序。然后 CPU 读取存储在入口点的指令(数字),并严格处理,顺序读取下一个数字作为进一步的指令,除非程序本身告诉 CPU 继续在别处执行。
例如,两个 8 位数字(8 位组合在一起等于 1 个字节,这是 0-255 范围内的无符号整数):60
201
,当作为 Zilog Z80 CPU 上的代码执行时,将作为两个指令处理:INC a
(寄存器 a
中的值递增一个)和 RET
(从子程序返回,指向 CPU 执行来自存储器不同部分的指令)。
为了定义该程序,人类可以通过某些存储器/文件编辑器输入这些数字,例如在十六进制编辑器中输入两个字节:3C C9
(以 16 进制编码写入的十进制数 60 和 201)。那将是机器代码*编程 ***** 。
为了使人类更容易编写 CPU 编程任务,创建了一个 Assembler 程序,能够读取包含以下内容的文本文件:
subroutineIncrementA:
INC a
RET
dataValueDefinedInAssemblerSource:
DB 60 ; define byte with value 60 right after the ret
输出字节十六进制数字序列 3C C9 3C
,包含特定于目标平台的可选附加数字:标记此类二进制文件的哪一部分是可执行代码,其中是程序的入口点(其中的第一条指令),哪些部分是编码数据(不可执行)等
注意程序员如何将值为 60 的最后一个字节指定为数据,但从 CPU 的角度来看,它与 INC a
字节没有任何区别。由执行程序正确导航 CPU 作为指令准备的字节,并仅将数据字节作为指令数据处理。
这样的输出通常存储在存储设备上的文件中,稍后由 OS( 操作系统 - 已经在计算机上运行的机器代码,有助于与计算机一起操作 )在执行之前加载到内存中,最后将 CPU 指向程序的切入点。
CPU 只能处理和执行机器代码 - 但是任何内存内容,甚至是随机内存,都可以这样处理,虽然结果可能是随机的,从 OS 检测和处理的 崩溃到意外擦除 I /中的数据 O 设备,或连接到计算机的敏感设备的损坏(不是家用电脑的常见情况:))。
许多其他高级编程语言遵循类似的过程,将源 (人类可读的文本形式的程序) 编译成数字,或者代表机器代码(CPU 的本机指令),或者在解释/混合语言的情况下编译成一般的特定于语言的虚拟机代码,在解释器或虚拟机执行期间进一步解码为本机机器代码。
有些编译器使用 Assembler 作为编译的中间阶段,首先将源转换为 Assembler 形式,然后运行汇编工具从中获取最终的机器代码 (GCC 示例:运行 gcc -S helloworld.c
以获得 C 程序的汇编版本 helloworld.c
)。