一个程序要vm的代码里有几句push pop指令,那vmp虚拟机在遇到这种指令要怎么处理。毕竟vmp自己也是基于堆栈的虚拟机。它会把这些与堆栈操作有关的指令是在真实的堆栈上处理,还是在vmp的虚拟堆栈里处理?
1条回答 默认 最新
- FadeTrack 2021-08-31 18:21关注
这种需要和宿主打交道的vm,其操作最终会反应到真实机器的寄存器和内存(也就是你这里说的真实的栈,即操作esp和其指向的内容)。
举个例子,伪代码
typedef struct vcpu { uint32_t eax; uint32_t ebx; uint32_t ecx; // .... uint32_t esp; } vcpu; void foo() { printf("entry_vm\n"); entry_vm(); do_vmcode(vpush, value, 0); do_vmcode(vadd, eax, ebx); exit_vm(); // 注意 vpush之后这里栈没平衡 printf("exit_vm\n"); }
这里的 entry_vm 和 exit_vm 一般采用汇编构造,在 entry_vm 阶段保存当前寄存器信息到vcpu结构,exit_vm() 反之。
do_vmcode 会对 vcpu 结构进行操作。do_vmcode(vpush, value) 操作对应
vcpu->esp-=4; *(int*)(vcpu->esp) = value;
do_vmcode(vadd, eax, ebx) 操作对应vcpu->eax += vcpu->ebx;
通过以上方式就可以简单将原始汇编二进制转为等价的 vmcode (通常是更为简洁的自定义指令集),这里为了简单用了一一对应的指令关系。
一般流程是 entry_vm 保存寄存器信息后,会进入一个环境初始化部分(负责异常处理等),然后开始一个循环,读取 vcpu->eip 指向的 vmcode,然后调用 do_vmcode 完成上述解析执行操作,直到退出vm,调用 exit_vm(反应寄存器信息回真实机器),在 do_vmcode 中操作的内存即是真实内存,故内存操作在vm内部已经被反应(也可以像 qemu 那样搞个 vmmu,可以,但没必要)。
实际上这种vm最难的地方在于重定位,异常等处理上面,希望有天你能分析分析,写篇报告。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报
悬赏问题
- ¥15 yolov8边框坐标
- ¥15 matlab中使用gurobi时报错
- ¥15 WPF 大屏看板表格背景图片设置
- ¥15 这个主板怎么能扩出一两个sata口
- ¥15 不是,这到底错哪儿了😭
- ¥15 2020长安杯与连接网探
- ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
- ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
- ¥16 mybatis的代理对象无法通过@Autowired装填
- ¥15 可见光定位matlab仿真