Write your Own Virtual Machine - L2_LC-3 Architecture

前言:这是 Write your Own Virtual Machine 的第二篇文章。主要是来介绍 LC-3 Architecture。原文在这里

LC-3 架构(LC-3 Architecture)

我们的 VM 会要模拟一个功能性的计算机 — LC-3。LC-3 非常适合教大学生如何用汇编语言编程。与 x86 相比,它具有简化的指令集,但包含现代 CPU 中使用的所有主要思想。

首先,我们需要模拟机器的基本硬件组件。尝试了解每个组件是什么。首先创建一个 C 文件。本节中的每个代码段都应放在此文件的全局范围内。

内存(Memory)

LC-3 有 65,536 个内存地址(最大的是 16 位无符号整数 ),每个内存地址存储一个 16 位的值。这意味着整个内存可以存储 128KB,这非常小。在我们的程序中,这个内存用一个简单的数组储存。

/* 65536 locations */
uint16_t memory[UINT16_MAX];

寄存器(Registers)

寄存器是用于在 CPU 上存储单个值的插槽。寄存器就像 CPU 的“工作台”。要使 CPU 处理一段数据,它必须位于其中一个寄存器中。但是,由于只有几个寄存器,因此在任何给定时间只能加载少量的数据。程序通过将内存中的值加载到寄存器中,将值计算到其他寄存器中,然后将最终结果存储回内存来解决此问题。

LC-3 共有10个寄存器,每个寄存器为 16 位。他们中的大多数是通用的,只有少数寄存器被指定了用途。

  • 8 个通用寄存器(R0 - R7)
  • 1 个程序计数器(PC)
  • 1 个条件标志(COND)寄存器

通用寄存器可用于执行任何程序计算。程序计数器是无符号整数,它是要执行的内存中下一条指令的地址。条件标志告诉我们有关先前计算的信息。

enum
{
    R_R0 = 0,
    R_R1,
    R_R2,
    R_R3,
    R_R4,
    R_R5,
    R_R6,
    R_R7,
    R_PC, /* program counter */
    R_COND,
    R_COUNT
};

就像内存一样,我们在数组中存储寄存器。

uint16_t reg[R_COUNT];

指令集(Instruction Set)

指令是一个命令,它告诉 CPU 执行一些基本任务,例如两个数字相加。指令具有指示要执行的任务类型的操作码(opcode)和一组为正在执行的任务提供输入的参数(parameters)。

每个操作码(opcode)代表一个 CPU “知道”如何去做的任务。 LC-3 中只有 16 个操作码。计算机可以计算的任何东西都是这些指令的组合。每条指令长 16 位,左边 4 位存储操作码。其余位用于存储参数。

稍后,我们将详细讨论每个指令会做什么。现在,定义以下操作码。确保它们保持此顺序,以便为它们分配正确的枚举值:

enum
{
    OP_BR = 0, /* branch */
    OP_ADD,    /* add  */
    OP_LD,     /* load */
    OP_ST,     /* store */
    OP_JSR,    /* jump register */
    OP_AND,    /* bitwise and */
    OP_LDR,    /* load register */
    OP_STR,    /* store register */
    OP_RTI,    /* unused */
    OP_NOT,    /* bitwise not */
    OP_LDI,    /* load indirect */
    OP_STI,    /* store indirect */
    OP_JMP,    /* jump */
    OP_RES,    /* reserved (unused) */
    OP_LEA,    /* load effective address */
    OP_TRAP    /* execute trap */
};

Note:英特尔 x86 架构有数百条指令,而 ARM 和 LC-3 等其他指令则很少。小指令集称为 RISC,而较大指令集称为 CISC。较大的指令集通常不提供任何在根本上新的指令,而是使写汇编的时候更加方便。CISC 中的单个指令可能取代 RISC 中的几个指令。然而,对于工程师来说,它们设计和制造往往更复杂和昂贵。

条件标志(Condition Flags)

R_COND 寄存器存储条件标志,提供最近执行计算的有关信息。这允许程序检查逻辑条件,例如 if(x > 0){...}。

每个 CPU 都有各种条件标志来指示各种情况。 LC-3 仅使用 3 个条件标志,表示先前计算的符号。

enum
{
    FL_POS = 1 << 0, /* P */
    FL_ZRO = 1 << 1, /* Z */
    FL_NEG = 1 << 2, /* N */
};

Note:<< 符号称为左位移操作符。(n << k) 将 n 的所有位移位到左k 位。因此 1 << 2 将等于 4(1 -> 100 = 4).如果你不熟悉,请阅读该链接。这很重要。

我们已经完成了 VM 硬件组件的设置!

最后

GitHub

点个喜欢呗

你可能感兴趣的:(Write your Own Virtual Machine - L2_LC-3 Architecture)