- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
指令执行主循环——cpu_exec().docx
指令执行主循环 — — cpu_exec()
void cpu_exec(volatile uint32_t n) {
if(nemu_state == END) {
printf(Program execution has ended. To restart the …….\n);
return;
}
nemu_state = RUNNING;
……….
setjmp(jbuf);
for(; n 0; n --) {
…………..
int instr_len = exec(cpu.eip);
cpu.eip += instr_len;
……………..
if(nemu_state != RUNNING) { return; }
}
if(nemu_state == RUNNING) { nemu_state = STOP; }
}
//执行当前%eip所指向的指令
//指向下一条指令的%eip
所在文件:~/monitor/cpu-exec.c
NEMU中指令的执行
重点关注“工程路径/nemu/include/cpu”和“工程路径/nemu/src/cpu”
关键的宏定义:
#define make_helper(name)
//位于“nemu/include/cpu/helper.h”
#define make_helper_v(name)
//位于“nemu/include/cpu/exec/helper.h”
#define make_instr_helper(type)
//位于“nemu/include/cpu/exec/helper.h”
NEMU如何执行指令?— — exec()
exec()函数在哪个文件中?
工程路径/nemu/src/cpu/exec/exec.c
make_helper(exec) {
ops_decoded.opcode = instr_fetch(eip, 1);
return opcode_table[ ops_decoded.opcode ](eip);
}
#define make_helper(name) int name(swaddr_t eip)
int exec (swaddr_t eip) {
ops_decoded.opcode = instr_fetch(eip, 1);
return opcode_table[ ops_decoded.opcode ](eip);
}
该宏定义一系列“helper”函数,每个“helper”函数对%eip指向内存单元进行操作,并返回操作涉及的代码长度。
保存译码相关的信息,如操作码,源操作数,目的操作数等
NEMU的指令周期 — — 取指IF
函数instr_fetch( )负责取指工作,位于“nemu/include/cpu/helper.h”
static inline uint32_t instr_fetch(swaddr_t addr, size_t len) {
return swaddr_read(addr, len);
}
NEMU的指令周期 — — 译码ID(1)
确定是哪一条指令的哪一种形式(opcode)
确定操作数(ModR/M, SIB, Displacement以及Immediate)
int exec (swaddr_t eip) {
ops_decoded.opcode = instr_fetch(eip, 1);
return opcode_table[ ops_decoded.opcode ](eip);
}
helper_fun opcode_table [256] = {…};
typedef int (*helper_fun)(swaddr_t);
opcode_table数组中每一个元素是一个函数指针(helper函数),对应某条指令的某种形式
NEMU的指令周期 — — 译码ID(2)
100014: b9 00 80 00 00 mov $0x8000,%ecx
......
1000fe: 66 c7 84 99 00 e0 ff movw $0x1,-0x2000(%ecx,%ebx,4)
100105: ff 01 00
首先通过instr_fetch()取得指令的第一个字节0xb9;
根据字节0xb9索引opcode_table,找到一个名为mov_i2r_v( )的helper函数
指令所对应的helper函数的通
文档评论(0)