当前位置: 首页 > news >正文

一生一芯 预学习阶段 NEMU代码学习(2)

接上回:一生一芯 预学习阶段 NEMU代码学习(1)

上次说到这里

static int cmd_c(char *args) {cpu_exec(-1);return 0;
}

当输入c时,会执行:cpu_exec(-1);

void cpu_exec(uint64_t n) {g_print_step = (n < MAX_INST_TO_PRINT);switch (nemu_state.state) {case NEMU_END: case NEMU_ABORT:printf("Program execution has ended. To restart the program, exit NEMU and run again.\n");return;default: nemu_state.state = NEMU_RUNNING;}uint64_t timer_start = get_time();execute(n);uint64_t timer_end = get_time();g_timer += timer_end - timer_start;switch (nemu_state.state) {case NEMU_RUNNING: nemu_state.state = NEMU_STOP; break;case NEMU_END: case NEMU_ABORT:Log("nemu: %s at pc = " FMT_WORD,(nemu_state.state == NEMU_ABORT ? ANSI_FMT("ABORT", ANSI_FG_RED) :(nemu_state.halt_ret == 0 ? ANSI_FMT("HIT GOOD TRAP", ANSI_FG_GREEN) :ANSI_FMT("HIT BAD TRAP", ANSI_FG_RED))),nemu_state.halt_pc);// fall throughcase NEMU_QUIT: statistic();}
}

g_print_step 是一个全局变量,用于控制是否逐步输出执行的指令信息;

如果要执行的指令数量 n 小于预定义的常量 MAX_INST_TO_PRINT,则将 g_print_step 置为 true,表示会逐步打印指令执行的过程。

uint64_t timer_start = get_time();

uint64_t timer_end = get_time();

get_time() 函数返回当前的时间,用于记录 CPU 执行开始的时间以及指令执行结束时的时间。

并将执行的时间差累加到全局变量 g_timer 中。

最后,根据执行完后的 nemu_state.state 状态值进行判断;

如果 nemu_state.state == NEMU_ABORT:说明程序处于 "中止" 状态,输出 "ABORT",并且使用 ANSI_FG_RED 红色格式化显示。
否则,检查 nemu_state.halt_ret:
如果 halt_ret == 0,表示程序正常终止(触发了 "GOOD TRAP"),输出 "HIT GOOD TRAP",并使用 ANSI_FG_GREEN 绿色显示。
如果 halt_ret != 0,表示程序遇到错误终止(触发了 "BAD TRAP"),输出 "HIT BAD TRAP",并使用 ANSI_FG_RED 红色显示。

再看(execute(n);):

static void execute(uint64_t n) {Decode s;for (;n > 0; n --) {exec_once(&s, cpu.pc);g_nr_guest_inst ++;trace_and_difftest(&s, cpu.pc);if (nemu_state.state != NEMU_RUNNING) break;IFDEF(CONFIG_DEVICE, device_update());}
}

这个 execute 函数的作用是在 NEMU 中执行模拟 CPU 的指令。它会循环执行传入的 n 条指令,并在每次执行后进行跟踪、差异测试和设备状态更新。

exec_once(&s, cpu.pc);

static void exec_once(Decode *s, vaddr_t pc) {s->pc = pc;s->snpc = pc;isa_exec_once(s);cpu.pc = s->dnpc;
#ifdef CONFIG_ITRACEchar *p = s->logbuf;p += snprintf(p, sizeof(s->logbuf), FMT_WORD ":", s->pc);int ilen = s->snpc - s->pc;int i;uint8_t *inst = (uint8_t *)&s->isa.inst.val;for (i = ilen - 1; i >= 0; i --) {p += snprintf(p, 4, " %02x", inst[i]);}int ilen_max = MUXDEF(CONFIG_ISA_x86, 8, 4);int space_len = ilen_max - ilen;if (space_len < 0) space_len = 0;space_len = space_len * 3 + 1;memset(p, ' ', space_len);p += space_len;#ifndef CONFIG_ISA_loongarch32rvoid disassemble(char *str, int size, uint64_t pc, uint8_t *code, int nbyte);disassemble(p, s->logbuf + sizeof(s->logbuf) - p,MUXDEF(CONFIG_ISA_x86, s->snpc, s->pc), (uint8_t *)&s->isa.inst.val, ilen);
#elsep[0] = '\0'; // the upstream llvm does not support loongarch32r
#endif
#endif
}

http://www.lryc.cn/news/483381.html

相关文章:

  • 《手写Spring渐进式源码实践》实践笔记(第二十章 实现简单ORM框架)
  • AI技术赋能电商行业:创新应用与未来展望
  • windows 11编译安装ffmpeg(包含ffplay)
  • 系统启动时将自动加载环境变量,并后台启动 MinIO、Nacos 和 Redis 服务
  • [ACTF2020 新生赛]Upload 1--详细解析
  • power bi中的related函数解析
  • 目前区块链服务商备案支持的区块链技术类型
  • CatBoost中的预测偏移和排序提升
  • python: postgreSQL using psycopg2 or psycopg
  • 从 MySQL 5.7 到 8.0:理解 GROUP BY 的新规则与实战优化20241112
  • npm完整发包流程(亲测可验证)
  • 学习threejs,使用JSON格式保存和加载模型
  • 中国首部《能源法》正式问世,它的亮点有哪些呢?
  • 【外包】软件行业的原始形态,项目外包与独立开发者
  • 工程数学线性代数(同济第七版)附册课后习题答案PDF
  • 【Ubuntu24.04】部署服务(基础)
  • Linux符号使用记录
  • 初阶C++之C++入门基础
  • ODOO学习笔记(7):模块化架构(按需安装)
  • Java的dto,和多表的调用
  • 时序数据库TimescaleDB安装部署以及常见使用
  • MG算法(英文版)题解
  • 2-UML概念模型测试
  • 人工智能(AI)对于电商行业的变革和意义
  • 智能病历xml提取
  • RK3568平台开发系列讲解(GPIO篇)GPIO的sysfs调试手段
  • 使用 Web Search 插件扩展 GitHub Copilot 问答
  • workerman的安装与使用
  • QtQuick.Controls 控件介绍(都有哪些type)
  • Unity导出APK加速与导出失败总结(不定时更新)