在 x86 16 位机器代码中编写引导加载程序的问题

逆向工程 记忆 编码 机器码
2021-06-20 07:32:14

我在显示简单文本时遇到问题。我试图用机器代码来做这一切INT 10h,但是:

  1. INT 10h在英特尔手册中找不到任何地方的二进制操作码

  2. 我不知道如何加载“Hello world!”的二进制 ASCII 表示。输入到数据段寄存器(DS,需要12字节的数据来表示全文数据)。

我考虑通过直接写入内存映射的 VGA 内存来实现,但这似乎比使用来自 BIOS 的中断更难。而且我并不完全了解它是如何工作的。

任何人都可以帮我解决这个问题吗?我不需要 x86 指令本身的帮助,但是我需要如何正确地将这些全部编码为二进制,以及在哪里可以找到所有中断的操作码。

2个回答
  1. 要调用中断,您可能希望使用int imm8编码为0xcd, 0xnn0x10在这种情况下)。

  2. 对于引导加载程序,将数据粘贴jmp在引导加载程序的开头与其目标之间是很常见的ds除非您正在制作一个非常大的引导加载程序(从磁盘加载额外的扇区)否则您真的不需要搞砸

对于中断参考,如果您需要这样的东西,我可能会建议Ralph Browns Interrupt List

关于(2),您不会将整个字符串加载到段寄存器中,而是使用保存字符串的内存区域的选择器,并将放入段寄存器中。对于 16 位引导加载程序环境,它可能与 CS 相同,因此您只需push cs, pop ds(尽管通常cs=ds=es=ss已经在启动时)。

要写入显存,只需加载0xb800es,然后写入屏幕的蛮力方式如下所示:

mov es:[0], 'H'
mov es:[2], 'e'
mov es:[4], 'l'
mov es:[6], 'l'
mov es:[8], 'o'

等等。当然,这不是最佳方式。通常,您会使用循环和字符串操作,或者只使用 BIOS 调用。