虚拟机的原理-自己写一个虚拟机

虚拟机的原理其实非常简单,首先分配一块内存充当虚拟机的内存,然后再分配一块内存当作虚拟机的寄存器。

接下来,解析二进制文件,根据机器码的含义做对应的操作,比如机器码:

101110110000110101111100

8086机器码手册,可知它的意思是将一个立即数放到寄存器bx中,对应的汇编为:

mov bx, imm

在我们的程序中可以直接将代表bx的内存设置为imm,这条指令就算虚拟执行完了。之后将指令指针寄存器eip的值加1,这个寄存器记录了下一条指令的位置,其实就是将代表eip的内存中的值加1。

下一条指令,先取出eip的值,然后根据eip去内存中取指令:

1111111111100011

通过查手册发现其对应的汇编为

jmp bx

这是一条跳转指令,跳到bx寄存器中的地址执行,我们只需要将eip寄存器设置为bx的值就行了。

通过上面简单的例子,相信你已经明白了,虚拟机就是将硬件的功能转换为简单的内存的读写

前几天兴趣所致,还写了个简单的虚拟机demo,它能够执行下面的汇编:

    mov bx,0x7c00+start
    jmp bx

message:
    db 'ABC abc '

start:
    ;设置附加段基址到显示缓冲区
    mov ax,0x7c00
    mov ds,ax
    
    ;设置附加段基址到显示缓冲区
    mov ax,0xb800
    mov es,ax

    ;显示字符串 
    mov si,message          
    mov di,0
    mov cx,start-message
@g:
    mov al,[si]
    mov [es:di],al
    inc di
    mov byte [es:di],0x07
    inc di
    inc si
    loop @g

    ;停机
    hlt

  times 510-($-$$) db 0
                   db 0x55,0xaa

这段汇编的作用是将字符串移动到显示缓冲区中。

如果你对我写的虚拟机demo感兴趣也可以下载我的代码,体验一下。它是用python写的,需要安装python3环境,还需要nasm编译汇编程序,然后到目录下执行make,如果python提示缺少包,用pip3 install安装对应的包即可。

程序成功执行之后可以用浏览器打开index.html,他会将显示缓冲区中的内容可视化显示出来,相当于虚拟屏幕。

image

用上面的方法是完全用软件模拟,执行一条指令必须用几条指令进行解析,效率比原来慢几倍。随着虚拟化越来越重要,CPU和内存开始支持硬件辅助虚拟化,甚至一些高频外设也支持硬件辅助虚拟化。

KVM是一种使用硬件辅助虚拟化技术的虚拟机,它相比软件虚拟化速度有明显提升。现在的linux与QEMU中都有KVM的代码。

posted @ 2021-06-04 14:27:13
评论加载中...
发表评论