程序的执行和模拟器–学习笔记

回顾

用变量实现寄存器和内存

#include <stdint.h>
uint32_t R[32], PC; // according to the RISC-V manual
uint8_t M[64];      // 64-Byte memory

用语句实现指令的语义

指令周期(instruction cycle): 执行一条指令的步骤

  • 取指(fetch): 从PC所指示的内存位置读取一条指令
  • 译码(decode): 按手册解析指令的操作码(opcode)和操作数(operand)
  • 执行(execute): 按解析出的操作码, 对操作数进行处理
    • 若写入 < R, M>, 则更新状态
  • 更新PC: 让PC指向下一条指令
    • 更新状态

通过模拟每一个运行的过程,并不断的更新状态,执行语句,直到结束

初始状态

根据手册, 初始状态如下:

  • R[0] = 0, 0号寄存器恒为0
  • PC = 0, 与自制运行时环境共同约定
  • M中存放程序, 与自制运行时环境共同约定, 由模拟器加载程序

防御性编程

不相信外界的输入/其他函数传递的参数, 通过断言提前拦截非预期情况

编写可复用的代码

拒绝Copy-Paste

Copy-Paste = 编写相似代码时, 复制旧代码并稍作修改

  • 开发效率++, 维护难度+++++

上述代码不言自明本身就不怎么样, 不言自证就更难了

  • 需要看很久的代码, 基本上都很难做到不言自证
    • 而且你基本上没有耐心仔细看的 😂
  • 当你粘贴出上百行这样的代码, 你很可能会改漏几处
    • 哪天你发现了一个共性的问题(例如立即数忘记符号扩展), 所有粘贴的代码都要修改
    • 改漏了 = bug

粘贴一时爽, 调试火葬场 

编写可复用的代码

通过变量, 函数, 宏等方式消除重复/相似的代码

uint32_t inst = *(uint32_t *)&M[PC];
uint32_t opcode = inst & 0x7f;
uint32_t funct3 = (inst >> 12) & 0x7;
uint32_t rd  = (inst >> 7 ) & 0x1f;
uint32_t rs1 = (inst >> 15) & 0x1f;
uint32_t imm = ((inst >> 20) & 0x7ff) - ((inst & 0x80000000) ? 4096 : 0);
if (opcode == 0x13) {
  if      (funct3 == 0x0) { R[rd] = R[rs1] + imm; } // addi
  else if (funct3 == 0x4) { R[rd] = R[rs1] ^ imm; } // xori
  else if (funct3 == 0x6) { R[rd] = R[rs1] | imm; } // ori
  else if (funct3 == 0x7) { R[rd] = R[rs1] & imm; } // andi
  else { panic("Unsupported funct3 = %d", funct3); }
  R[0] = 0; // 若指令写入了R[0], 此处将其重置为0
} else if (...) {  ...  }
PC += 4;
  • 引入中间变量, 不言自明 ✅
  • 对齐的代码更容易阅读并发现错误, 不言自证 ✅

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇