【问题标题】:why these real-mode code works in virtual machine but not working on my real machine?为什么这些实模式代码可以在虚拟机上工作,但不能在我的真机上工作?
【发布时间】:2016-09-13 08:47:26
【问题描述】:

我正在尝试将汇编代码写入 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 处理器,我做错了什么?

【问题讨论】:

  • xor ax, axmov ss, axmov ds, ax之类的东西初始化段寄存器。指令mov al, [...] 使用dspush ... 使用ss。确保它们相等。
  • @MargaretBloom 这行得通!谢谢你 !请将其发布为答案,然后我可以将此问题标记为已回答。

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


【解决方案1】:

用类似的东西初始化段寄存器

xor ax, ax       ;Initialize seg regs with 0
mov ss, ax 
mov ds, ax 

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


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

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

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

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

【讨论】:

  • 由于 OP 没有明确禁用中断(理论上 BIOS 可以在跳转到引导扇区代码之前将它们保持打开状态),你认为更新 SS i> 也不改变 SP 吗?我可能只是明确表示,如果更新 SS:SP 你更新 SS 然后 SP 之后(更新到 SS 和中断一直关闭,直到以下指令结束)或仅使用 CLI 在启动代码期间将其关闭。
  • @MichaelPetch 你是绝对正确的。我正在更新答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-21
  • 2013-08-28
  • 1970-01-01
  • 2023-03-10
  • 2015-05-19
  • 2019-05-04
相关资源
最近更新 更多