CPU0 处理器的架构及应用

本文详细介绍了CPU0,一个32位处理器的架构,包括R0-R15、IR、MAR和MDR等寄存器及其功能。CPU0的指令集分为L型、A型和J型,支持加载储存、算术和跳跃操作。文章还提到了在CPU0_v2中新增的浮点运算指令,并讨论了状态缓存器如何影响条件跳转指令。此外,文章探讨了V-OS系统,一种可能的横跨操作系统与硬件的虚拟机设计,以及CC1编译程序的符号表和词汇分析过程。
摘要由CSDN通过智能技术生成

CPU0 处理器的架构及应用
简介
CPU0 是一个 32 位的处理器,包含 R0…R15, IR, MAR, MDR 等缓存器,结构如下图所示。
在这里插入图片描述

图 1 :CPU0 处理器的结构
其中各个缓存器的用途如下所示:
IR 指令缓存器
R0 常数缓存器, 值永远为 0。
R1~R11 通用型缓存器。
R12 状态缓存器 (Status Word : SW)
R13 堆栈指针缓存器 (Stack Pointer : SP)
R14 链接缓存器 (Link Register : LR)
R15 程序计数器 (Program Counter : PC)
MAR 地址缓存器 (Memory Address Register)
MDR 数据缓存器 (Memory Data Register)
CPU0 的指令集
CPU0 的指令分为三种类型,L 型通常为加载储存指令、A 型以算术指令为主、J 型则通常为跳跃指令,下图显示了这三种类型指令的编码格式。
在这里插入图片描述

图 2:CPU0 的三种指令格式
以下是 CPU0 处理器的指令表格式
表 1 :CPU0 的指令表
在这里插入图片描述

在第二版的 CPU0_v2 中,补上了以下指令:
类型 格式 指令 OP 说明 语法 语意
浮点运算 A FADD 41 浮点加法 FADD Ra, Rb, Rc Ra = Rb + Rc
浮点运算 A FSUB 42 浮点减法 FSUB Ra, Rb, Rc Ra = Rb + Rc
浮点运算 A FMUL 43 浮点乘法 FMUL Ra, Rb, Rc Ra = Rb * Rc
浮点运算 A FADD 44 浮点除法 FDIV Ra, Rb, Rc Ra = Rb / Rc
中断处理 J IRET 2D 中断返回 IRET PC = LR; INT 0
状态缓存器
CPU0 的状态缓存器,包含 N, Z, C, V 等状态,以及 I, T 等中断模式位。结构如下图所示。
在这里插入图片描述

图 3:CPU0 的状态缓存器
当 CMP Ra, Rb 指令执行时,状态标志会因而改变。
假如 Ra > Rb, 则会设定状态 N=0, Z=0
假如 Ra < Rb, 则会设定状态 N=1, Z=0
假如 Ra = Rb, 则会设定状态 N=0, Z=1
于是条件式跳跃的 JGT, JLT, JGE, JLE, JEQ, JNE 等指令,就可以根据状态缓存器中的 N, Z 标志进行跳跃操作。
指令的执行步骤
CPU0在执行一个指令时,必须经过取指、译码与执行等三大阶段。

  1. 提取阶段
    o 操作1、提取指令 :IR = [PC]
    o 操作2、更新计数器 :PC = PC + 4
  2. 解碼阶段
    o 操作3、解碼 :控制单元对IR进行译码后,设定数据流向开关与 ALU 的运算模式
  3. 运行时间
    o 操作4、执行 :数据流入 ALU,经过运算后,流回指定的缓存器
    V-OS: 横跨操作系统与硬件的虚拟机系统
  4. 设计一个虚拟机系统,可以将 CPU A, B, C, D, E … 模拟成另外任何一种 CPU,这样是否能解决所有的跨平台问题呢?
    o QEMU 其实可以做到类似的操作,想法与 QEMU 不同点在于 QEMU 是在操作系统层次之上的,做法是在操作系统层次之下的。
    o 这样子就可以将在任何一个 CPU 上,跑另一个操作系统的程序,但是,不知速度会比 QEMU 快还是慢呢?
    o 这种做法姑且可以想象为「云端虚拟机」!
    o 不知大家觉得可能吗?有用吗?
    在这里插入图片描述

图一:V-OS 系统的架构图
CC1 编译程序
为了说明编译程序是如何设计出来的,在开放计算机计划中,设计了一个功能完备,简化过的 C 语言,这个语言称为 C1 语言,是 C0 语言的扩充版。
CC1 编译程序是一个 C1 语言的编译程序,具有完成的编译程序功能。在程序设计上,CC1 又被进一步拆解为 1. 词汇分析 2. 语法分析 3. 语意分析 4. 中间码产生 5. 汇编语言产生 等阶段,这所有的阶段,都会存取一个共同的数据结构,就是符号表。
因此,整个 CC1 编译程序,进一步分解为下列程序模块。
模块 核心对象 程序
词汇分析 (Lexical Analysis) Scanner Scanner.c, Scanner.h
语法分析 (Syntax Analysis) Parser Parser.c, Parser.h
语意分析 (Semantic Analysis) Semantic Semantic.c, Semantic.h
中间码产生 (Intermediate Code) PCode PCode.c, PCode.h
汇编语言产生 (Code Generation) Generator Generator.c, Generator.h
符号表 (Symbol Table) SymTable SymTable.c, SymTable.h
Lua

  1. http://zh.wikipedia.org/wiki/Lua
    Lua 的 BNF
    chunk ::= {stat [;´]} [laststat [;´]]

    block ::= chunk

    stat ::= varlist =´ explist | functioncall | do block end | while exp do block end | repeat block until exp | if exp then block {elseif exp then block} [else block] end | for Name=´ exp ,´ exp [,´ exp] do block end |
    for namelist in explist do block end |
    function funcname funcbody |
    local function Name funcbody |
    local namelist [`=´ explist]

    laststat ::= return [explist] | break

    funcname ::= Name { .´ Name} [:´ Name]

    varlist ::= var {`,´ var}

    var ::= Name | prefixexp [´ exp]´ | prefixexp `.´ Name

    namelist ::= Name {`,´ Name}

    explist ::= {exp `,´} exp

    exp ::= nil | false | true | Number | String | `…´ | function |
    prefixexp | tableconstructor | exp binop exp | unop exp

    prefixexp ::= var | functioncall | (´ exp

    functioncall ::= prefixexp args | prefixexp `:´ Name args

    args ::= (´ [explist])´ | tableconstructor | String

    function ::= function funcbody

    funcbody ::= (´ [parlist])´ block end

    parlist ::= namelist […´] | `…´

    tableconstructor ::= {´ [fieldlist]

    fieldlist ::= field {fieldsep field} [fieldsep]

    field ::= [´ exp=´ exp | Name=´ exp | exp

    fieldsep ::= ,´ |

    binop ::= +´ |-´ | *´ |/´ | ^´ |%´ | ..´ |<´ | <=´ |>´ | >=´ |==´ | `~=´ |
    and | or

    unop ::= -´ | not |

  2. Lua 5.1 Reference Manual — http://www.lua.org/manual/5.1/manual.html
    o 最后有 Lua 的 BNF。

  3. Lua Interpreter in C — http://www.lua.org/source/5.1/lua.c.html

  4. Lua Compiler in Lua — http://lua-users.org/wiki/LuaCompilerInLua

  5. Lua Interpreter in Lua — http://lua-users.org/wiki/LuaInterpreterInLua

  6. http://luajit.org/ — The LuaJIT Project
    CC1 编译程序的符号表
    #ifndef SYMTABLE_H
    #define SYMTABLE_H

#include “lib.h”
#include “HashTable.h”
#include “Tree.h”

// 型态 Type 有:函数、结构与指针与基本型态
// 基本 : int x;
// 指标 : int *px;
// 函数 : int total(int a[]) {…};
// 结构 : struct Person { … };

typedef struct _Method {
char *name;
char *returnType;
Array *params;
} Method;

typedef struct _Struct {
char *name;
Array *fields;
} Struct;

typedef union _Type {
Method *pmethod;
Struct *pstruct;
char *pbtype;
} Type;

// 符号的值可能是 byte, int, float 或 pointer (包含 struct, method, type*)
typedef union _Value {
BYTE bvalue;
int ivalue;
float fvalue;
void *pvalue;
} Value;

// 变量符号: int x; Symbol(name=x, tag=VAR, type=int)
// 函数符号: int total(int a[]) {…}; Symbol(name=total, tag=METHOD, type=int)
// 结构符号: struct Person { … }; Symbol(name=x, tag=ETYPE, type=int)
typedef struct _Symbol { // 符号记录
void *scope; // 所属领域
char *name; // 符号名称 (x, px, Person, total)
char *tag; // 符号标记 (变量定义 VAR 函数定义 METHOD、结构定义 STRUCT)
Type type; // 符号的形态
Value value; // 符号的值
} Symbol;

typedef HashTable SymTable;

Symbol *SymNew(void *scope, char *name, char *tag);
void SymFree(Symbol *s);
void TypeFree(Type *type);

SymTable *SymTableNew();
Symbol *SymTablePut(SymTable *table, Symbol sym);
Symbol
SymTableGet(SymTable *table, void *scope, char *name);
void SymTableFree(SymTable *table);
void SymTableDebug(SymTable *table);

#endif
CC1 的词汇分析 (Scanner) 程序
档案:Scanner.h
#ifndef SCANNER_H
#define SCANNER_H

#include “lib.h”

typedef struct { // 扫描仪的对象结构
char *text; // 输入的程序 (text)
int len; // 程序的总长度
// 注意:以下的 xSave 都是在 ScannerStore() 与 ScannerRestore() 时使用的备份。
int i, iSave; // 目前词汇的位置
int line, lineSave; // 目前词汇的行号
int pos, posSave; // 目前词汇的起始点
char *tag, *tagSave; // 词汇的标记
char token[100], tokenSave[100]; // 目前的词汇
} Scanner;

void ScannerTest(char fileName); // Scanner 词汇分析阶段的测试程序。
Scanner
ScannerNew(char *pText); // 建立新的词汇分析 Scanner 对象
void ScannerFree(Scanner *s); // 释放 Scanner 对象
void ScannerStore(Scanner *s); // 储存 Scanner 的目前状态
void ScannerRestore(Scanner *s); // 恢复 Scanner 的储存状态
BOOL ScannerIsNext(Scanner *s, char *pTags); // 检查下一个词汇是否符合 tag 标记。
void ScannerNext(Scanner *s); // 取得下一个词汇 (token)
char ch(Scanner *s); // 取得目前字符
void cnext(Scanner *s); // 前进到下一个字符
char *tokenToTag(char *token); // 对词汇 (token) 进行标记 (tag)

// 宣告 Token 变量,包含关键词 if, for, 运算符 ++, / 与 非终端项目 IF, FOR…
#define DEF(var, str) extern char var[];
#include “Token.h”
#undef DEF

#endif
档案:Scanner.c
#include <string.h>
#include “Scanner.h”

// 宣告关键词的字符串变量,像是 char kIF[]=“if”; …char EXP[]=“EXP”;…
#define DEF(var, str) char var[]=str;
#include “Token.h”
#undef DEF

// 宣告关键词数组, gTagList={…,“if”, …,“EXP”, … };
char *gTokenList[] = {
#define DEF(var, str) var,
#include “Token.h”
#undef DEF
};

// 功能:Scanner 词汇分析阶段的测试程序。
// 范例:ScannerTest(“test.c1”);
void ScannerTest(char *fileName) {
debug(“ScannerTest()===\n”);
char *text = fileToStr(fileName); // 读取整个程序文件,成为一个字符串 text
Scanner *s = ScannerNew(text); // 建立 Scanner 对象
while (TRUE) { // 不断扫描词汇,直到档案结束
ScannerNext(s); // 取得下一个词汇
debug(“token=%-10s tag=%-10s line=%-4d pos=%-3d\n”,
s->token, s->tag, s->line, s->pos);
if (s->tag == kEND) // 已经到程序结尾
break; // 结束扫描
}
ScannerFree(s); // 释放 Scanner 对象
strFree(text); // 释放字符串 text
memCheck(); // 检查内存
}

// 功能:建立新的词汇分析 Scanner 对象
// 范例:Scanner s = ScannerNew(text);
Scanner
ScannerNew(char *pText) {
Scanner *s = ObjNew(Scanner, 1);
s->text = pText;
s->len = strlen(pText);
s->i = 0;
s->line = 1;
s->pos = 1;
// ScannerNext(s);
return s;
}

// 功能:释放 Scanner 对象
// 范例:ScannerFree(s);
void ScannerFree(Scanner *s) {
ObjFree(s);
}

// 功能:储存 Scanner 的目前状态
// 说明:剖析时若「偷看」后面几个 token,就必须使用 ScannerStore() 储存,然后呼叫
// ScannerNext() 偷看,之后再用 ScannerRestore() 恢复,以完成整个偷看过程。
// 范例:ScannerStore(s);
void ScannerStore(Scanner *s) {
s->iSave = s->i;
s->posSave = s->pos;
s->lineSave = s->line;
s->tagSave = s->tag;
strcpy(s->tokenSave, s->token);
}

// 功能:恢复 Scanner 的储存状态
// 范例:ScannerRestore(s);
void ScannerRestore(Scanner *s) {
s->i = s->iSave;
s->pos = s->posSave;
s->line = s->lineSave;
s->tag = s->tagSave;
strcpy(s->token, s->tokenSave);
}

// 功能:检查下一个词汇是否符合 tag 标记。
// 范例:if (ScannerIsNext(s, “+|-|*|/”)) ScannerNext(s);
BOOL ScannerIsNext(Scanner *s, char *pTags) { // 检查下一个词汇的型态
char tTags[MAX_LEN+1];
sprintf(tTags, “|%s|”, pTags);
if (strPartOf(s->tag, tTags))
return TRUE;
else
return FALSE;
}

// 功能:取得目前字符
// 范例:while (strMember(ch(s), DIGIT)) cnext(s);
char ch(Scanner *s) {
return s->text[s->i];
}

// 功能:前进到下一个字符
// 范例:while (strMember(ch(s), DIGIT)) cnext(s);
void cnext(Scanner *s) {
s->i++;s->pos++;
}

#define OP "±/%<=>!&|" // 运算符号字符集 (用来取得 +,-,,/, ++, …)

// 功能:Scanner 词汇分析阶段的测试程序。
// 范例:ScannerTest(“test.c1”);
void ScannerNext(Scanner s) { // 扫描下一个词汇
while (strMember(ch(s), SPACE)) { // 忽略空白
if (ch(s)==’\n’) {
s->line+&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值