Bochs vs. VMware
熟悉 Bochs 的人看了这个题目多半都会认为 Bochs 和 VMware 没有可比性,虽然 Bochs 运行图形系统的速度会让你有种奔向黑洞的感觉...
Kris Kaspersky 在《Hacker Debugging Uncovered》一书里列举过他原来实验的一些数据:
+-----------------------------+
| 宿主机 PIII 733MHz |
+-----------------------------+
| VMware PIII 366MHz |
| Virtual PC PIII 187MHz |
| Bochs PIII 1.49MHz |
+-----------------------------+
嘿嘿~ Bochs 大致相当于 0.203%。当然,这样计算是非常不准确的,这里只是示意一下。 ^_^
Virtual PC 甚至不能跑 SoftICE,玩家级的东西还是算了吧。VMware 较好的支持了 SoftICE 但是不能进行 OS 级调试(不过,我想他们要是想做也是绝对能做的),这时候 Bochs 的 Emulator 的概念就出来了,这东西整个就是一硬件的 ICE,价值不言而喻。
呃,今天真正想说的是 VMware 的 Bug......
感觉 VMware 底层许多地方做的不细,小问题不少,我随便测测就发现了:(1) 启动时不检测启动扇区 0xAA55 的 Magic Number;(2) 保护模式退回实模式时不判断 CR0 PE (Protection Enabled) 位是否清0;(3) 貌似根本就不支持 BIOS int 10h号中断 00h号功能调用(显示模式切换) 等等等等。
所以,VMware 也是非常面向应用的,想开发属于自己的操作系统的人是不会喜欢他们的。
最后放一段我的测试代码 —— 显示模式切换,将开机后默认的“80×25 16色文本模式”切换至“320×200 4色图形模式,并操作像素点绘制4条直线”。这段(引导扇区)代码在 Bochs 下工作的非常好,而 VMware 下则是种种怪异的现象~ 我想我应该是写了非常详细的注释,感兴趣的朋友瞅瞅吧~ ^_^
[为了方便显示(22' 液晶显示屏的人除外),下面代码做了进缩]
; ==================================================== ;
; .: keenjoy95 2007 :. ;
; .: keenjoy95_at_gmail_dot_com :. ;
; ---------------------------------------------------- ;
; 代码描述 : 引导扇区演示程序 ;
; 编译方法 : nasm boot.asm -o boot.bin ;
; ==================================================== ;
org 07c00h ; ORG伪指令也被称为程序起始地址伪指令 / 定位伪指令
; 该伪指令用于指示编译器(链接器)将其后续代码(段)定位于指定地址
; 由于本示例是引导扇区演示程序,所以目标定位地址为0000:7c00h
jmp MYOS_ENTRY ; 无条件跳转到程序的入口点MYOS_ENTRY标号处
SetVideoMode:
mov ax, 0004h ; 320 * 200 * 4 图形模式
; ---------------------------------------------------
; 0(00h) 319(13fh)
; 0(00h)┏━━━━━━━━━━━━━━━━┓
; ┃ ┃
; ┃ ┃
; ┃ ┃
; ┃ 显示器 320 * 200 显示方式 ┃
; ┃ 4 种色彩 ┃
; ┃ ┃
; ┃ ┃
; 199(C7h)┗━━━━━━━━━━━━━━━━┛
;
int 10h ; BIOS 10h号中断-00h号功能 (视频模式切换功能调用)
ret ; 子程序无参数返回
SetBackGround:
mov ah, 0bh
mov bx, 0001h ; 背景颜色设置为蓝色
int 10h ; BIOS 10h号中断-0Bh号功能 (背景颜色设置功能调用)
ret ; 子程序无参数返回
WriteGraphicsPixel:
mov cx, 0 ; Y 坐标设置
mov dx, 20 ; X 坐标设置
Back1: ;
mov ax, 0c01h ; 320 * 200 * 4 图形模式像素颜色设置
int 10h ; BIOS 10h号中断-0ch号功能 (像素写模式功能调用)
inc cx ; ┓
cmp cx, 320 ; ┣ X 坐标递增至屏幕宽度
jnz Back1 ; ┛
; ---------------------------------------------------------
mov cx, 0 ; Y 坐标设置
mov dx, 180 ; X 坐标设置
Back2: ;
mov ax, 0c01h ; 320 * 200 * 4 图形模式像素颜色设置
int 10h ; BIOS 10h号中断-0ch号功能 (像素写模式功能调用)
inc cx ; ┓
cmp cx, 320 ; ┣ X 坐标递增至屏幕宽度
jnz Back2 ; ┛
; ---------------------------------------------------------
mov cx, 20 ; Y 坐标设置
mov dx, 0 ; X 坐标设置
Back3: ;
mov ax, 0c02h ; 320 * 200 * 4 图形模式像素颜色设置
int 10h ; BIOS 10h号中断-0ch号功能 (像素写模式功能调用)
inc dx ; ┓
cmp dx, 200 ; ┣ Y 坐标递增至屏幕高度
jnz Back3 ; ┛
; ---------------------------------------------------------
mov cx, 300 ; Y 坐标设置
mov dx, 0 ; X 坐标设置
Back4: ;
mov ax, 0c03h ; 320 * 200 * 4 图形模式像素颜色设置
int 10h ; BIOS 10h号中断-0ch号功能 (像素写模式功能调用)
inc dx ; ┓
cmp dx, 200 ; ┣ Y 坐标递增至屏幕高度
jnz Back4 ; ┛
ret ; 子程序无参数返回
ScrollWindows:
mov ax, 0600h ; AH 赋值为功能号06h(窗口上滚) (BIOS INT 10-06h 定义参数)
; AL 赋值为0, 窗口信息全部移出(清屏) (BIOS INT 10-06h 定义参数)
mov bx, 0700h ; BH 底部空白行属性赋值为黑底灰白字 (BIOS INT 10-06h 定义参数)
; BL 保留
mov cx, 0000h ; 窗口左上角的行列、号赋值为00h 00h (BIOS INT 10-06h 定义参数)
mov dx, 184fh ; 窗口右下角的行列、号赋值为18h 4fh (BIOS INT 10-06h 定义参数)
; ---------------------------------------------------
; 0(00h) 79(4fh)
; 0(00h)┏━━━━━━━━━━━━━━━━┓
; ┃ ┃
; ┃ ┃
; ┃ ┃
; ┃ 显示器 25*80 显示方式 ┃
; ┃ ┃
; ┃ ┃
; ┃ ┃
; 24(18h)┗━━━━━━━━━━━━━━━━┛
;
int 10h ; BIOS 10h号中断-06h号功能 (清屏功能调用)
ret ; 子程序无参数返回
MYOS_ENTRY:
mov ax, cs ; ┓
mov ds, ax ; ┣ 段寄存器初始化
mov es, ax ; ┛
call ScrollWindows ; 调用清除屏幕子程序
call SetVideoMode ; 调用视频模式切换子程序
call SetBackGround ; 调用背景颜色设置子程序
call WriteGraphicsPixel ; 调用绘图子程序
jmp $ ; 主程序进入无限循环
MYOS_PAD:
times 510-($-$$) db 0 ; 循环填充剩余空间,使生成的二进制代码大小恰好为一个扇区(512Byte)
dw 0xAA55 ; 引导扇区结束标志
; ---8<--------------- [Cut Here] --------------->8--- ;
; .: keenjoy95 2007 :. ;
; .: keenjoy95_at_gmail_dot_com :. ;
; ! NO rights reserved ! ;
; ---------------------------------------------------- ;
NUPT WANGyu