如何从汇编语言直接与硬件接口



因此,我决定在今年夏天学习80x86的汇编语言。我拿起了四本关于集会的书。到目前为止,我已经读了前两篇,第三篇已经读到一半了,我想我理解了所呈现的一切。我已经写了一些Hello World程序以及书中的其他小练习,我对语言感觉很舒服。然而,有一件事到目前为止还没有一本书涉及,这也是我最感兴趣的事情。那就是,如何直接从汇编语言中解决硬件问题?到目前为止,作者在书中使用了系统调用、跳转到内存中的特定函数和中断,但这些方法依赖于系统中已经存在的软件。

我正在使用NASM编写程序,并将它们加载到一台旧的Pentium I计算机中。我现在没有使用任何操作系统,只是使用BIOS。我想我要做的是编写一个自主的、不依赖BIOS的小操作系统(除了初始引导)。有人能帮我吗?

如何仅使用BIOS引导和运行代码?

假设你真的只使用BIOS,或者即使你使用DOS,那也没关系。您只需对硬件进行寻址,在指令中指定某个硬件寄存器的地址,或者将该地址放入寄存器中,然后进行寄存器间接读取或写入。

只有在操作系统阻碍的情况下,访问硬件才是困难的,当然,使用操作系统让硬件做一些有用的事情要容易得多。

幸运的是,BIOS已经枚举了pci(e)硬件,这是PC的工作方式,所以你可以使用一些DOS实用程序来了解硬件是如何枚举的。另一种"PC做事的方式"硬件的PCI(e)地址也是x86地址,这两个地址空间重叠,所以一旦你得到某个外围设备的PCI(e)地址,你就可以在代码中使用该地址。当然,由于pcie窗口对于视频之类的东西来说相对较小,您仍然需要在外围存储器中分页,但这是外围特定的,而不是PC或x86之类的东西。

如果你的主板有一个串行端口/uart,那将是直接访问硬件的最佳起点。

更好的方法是使用模拟器pcemu或其他,而不是从硬件上开始,根据你选择的模拟器,你可能会更好地了解正在发生的事情,而像uart这样的外设可能会简单得多,因为你可能不必初始化它,只需开始向它抛出字节(直到你了解更多)。

dwelch完全正确,但我想从更基本的层面回答您的问题:
在大多数情况下,您可以通过控制和状态寄存器访问硬件。在最简单的情况下,例如,您想从串行线路读取,并且正在等待新字符到达。状态寄存器可以设置一个位"就绪",然后从另一个寄存器中读取字符
这意味着你必须寻址寄存器,比如内存地址。同样,在大多数情况下,这是通过将寄存器映射到地址空间来完成的,即寄存器的内存地址在没有内存的地址范围内,例如最顶层的地址。然后,您可以使用大多数访问内存的指令,例如加载和存储
在现实世界中,情况更为复杂,因为CPU使用的虚拟地址由可编程内存管理单元映射到物理地址空间(寄存器所在的位置)。

最新更新