NEMU PA 2-1 实验报告
一、实验目的
通过PA2-0了解了汇编基础知识和如何去阅读i386手册后,在这个阶段我们就需要:
- 了解程序执行的宏观过程,以及在NEMU中是怎么去模拟的
- 实现庞大的指令体系,实现每条指令的解码和具体执行过程
二、实验步骤
首先我们了解了程序执行的过程:
即首先需要装载可执行文件到内存,然后不断读取文件中的内容进cpu中,由cpu来实现解码,完成对一条条指令的执行。
在了解程序装载的这一步中,我们知道了:
- 程序装载在NEMU中内存的部位,其中ELF装载在RAMdisk区域(暂时这样划分内存),镜像文件装载到物理内存区域;装载方式为直接拷贝;
- NEMU初始化cpu,将EIP和ESP分别初始化到镜像文件起点和内存尾部;
在了解程序执行的这一步中,我们需要做:
-
了解程序执行这个循环往复的过程,代码位于:
nemu/src/cpu/cpu.c
-
了解指令是如何解码的,包括指令的汇编表示形式(AT&T和Intel),单独一条指令需要遵从的机器格式,并通过i386手册把指令“翻译”过来
在这一阶段我们的直接目标是通过所有这个阶段的测试样例,最终目标是把所有需要实现的指令都给它实现完成。
基本的步骤为:
-
修改
Makefile
中run
目标规则中的<testcase_name>
,指定要执行的测试用例。或使用make test_pa-2-1
自动执行各个测试用例; -
若遇到
invalide opcode
错误,则使用./scripts/objdump4nemu-i386 -d testcase/bin/<testcase_name>
查看测试用例反汇编结果,看看到底是缺了哪条指令,查阅i386手册详细了解这条指令。 -
实现这条指令,完成指令对应的
instr_func
,过程中可以借用已经给出的宏,可以在结构相同的操作中省心省力。 -
将指令其加入
opcode_entry[]
数组,替换对应位置上的inv
指令。框架代码已经提供了一部分指令的实现,只是没有填入opcode_entry[]
,比如mov.S
所需要的所有指令);
重复上述过程,直至通过所有这一阶段要求的测试用例,见到Hit Good Trap。
三、思考题
test-float
测试用例是唯一的一个例外,它理应Hit Bad Trap,请在实验报告中简述为什么?
因为在给float变量赋值的过程中会发生精度丢失,导致将值1.2赋值到a的时候,a的实际表示值并不为1.2,而是1.20000005(同样也是一个近似值);故在进行条件比较跳转时,即使在字面上似乎条件为true,但实际上则因为精度问题而为false,导致了后面的badtrap。