为什么这些实模式代码在虚拟机中工作但不能在我的真机上工作?

时间:2016-09-13 08:47:27

标签: assembly x86 x86-64 real-mode mbr

我正在尝试将汇编代码写入mbr以使用BIOS ISR。我将以下代码写入mbr,期望在屏幕上打印字符“ABCD”:

mov ah,0x0e
mov bp,0x8000
mov sp,bp

push 'A' 
push 'B'
push 'C'
push 'D'

mov al, [0x7ffe]
int 0x10

mov al, [0x7ffc]
int 0x10

mov al, [0x7ffa]
int 0x10

mov al, [0x7ff8]
int 0x10

; infinite loop
jmp $

; padding 0s and set the  magic number to make it bootable
times 510 -( $ - $$ ) db 0     
dw 0xaa55

这些代码在bochs或qemu模拟器上运行良好,但是当我写入我的真实磁盘并使用它来启动时,没有任何内容被打印出来。我已经测试过将%al寄存器直接设置为chars,打印效果很好。我使用的是AMD PhenomII 955处理器,我做错了什么?

1 个答案:

答案 0 :(得分:3)

之类的东西初始化段寄存器
xor ax, ax       ;Initialize seg regs with 0
mov ss, ax 
mov ds, ax 

指令mov al, [...]使用dspush ...使用ss
确保它们是平等的。

我没有提到它,但正如Michael正确指出的那样,在更新SS时必须小心。
对于中断,对SS:SP必须以原子方式进行更新,否则在初始化过程中触发的中断将使用SS:SP对不完全有效。

最简单的方法是在初始化sp之后更新ss

mov bp, 0x8000
mov ss, ax
mov sp, bp

因为mov ss, ...之后CPU禁止整个指令的中断 否则,您可以将初始化代码明确地包装在cli sti对中。