我最近得到了很大的怀旧情绪(以及重新回到CPU内部的痒),所以我决定自制一个8086微电脑板。当然,我熟悉x86程序集(在某种程度上,正如您所见)并且我已经知道如何将代码放到计算机主板上,让我们解决实际问题。为了获得通知,我使用NASM虽然我还没有完全掌握它的语法速度。
显然,在模式下工作的8086(实模式尚未被称为实模式)在开始时将最初的1,024个字节分开,用于255个2 + 2字节中断向量,因此实际指令列表从{{1开始}}。
这里的问题是因为系统内存分割的怪癖,以及我可能从编写系统的角度来编写BIOS的事实。是否必须设置段寄存器,如果是,我如何确定放在那里的内容?假设我使用EEPROM或某种形式的Flash进行代码存储,所以我有类似的东西:
0x3FF
我知道这可能是非常糟糕的,而且很可能显然是错误的语法,但它说明了我想要做的事情。我是否必须通过类似section .text
org 0x0000
; Interrupt vectors reserved
ivt: times 1024 db 0
main:
cli ; Clear out interrupts because no addresses are defined yet
; Problems HERE.
; Set up interrupt addresses
的方式手动设置分段寄存器,如果是,我如何确定代码体中不同段/节的地址?
这个问题的标题提到了这样一个事实,虽然我已经做了很多谷歌搜索,但我无法为我的生活找到8086的无操作系统编程的参考我能找到的所有资源都假设我正在编写一个已经存在的系统,其中已经设置并计算出中断向量和段等,而我试图制作一个可以完成所有工作的仿冒微控制器。磨砺。
答案 0 :(得分:4)
8086使用非常简单的表单分段,其中每个内存引用都基于四个段寄存器之一,CS
,DS
,SS
或ES
。这意味着无论是否在指令中显式,分段始终用于每个内存访问。为了解析存储器引用,CPU将相应段寄存器中的值乘以16,并将其添加到16位偏移量,得到20位物理地址。这就是现代英特尔处理器中所谓的实模式分割。
CS
寄存器确定代码段的基础。所有指令提取都在此段中以IP
寄存器提供的偏移量完成。由于Nathan Fellman的回答表明CS:IP
在处理器初始化期间加载了FFFF:0000
,因此给出了FFFF0h
的说明物理地址,因此您需要在此地址处安装EEPROM或其他内容。正如您的问题所述,您可能还需要在中断向量表的物理地址空间的开头有一些表单内存。
您找到的任何其他内容由您决定。您需要加载DS
寄存器,使其指向要存储大部分数据的位置,因为大多数内存操作数默认使用此段。您可能还希望拥有一个堆栈,因此您还需要使用合适的值加载SS
(和SP
)。如果需要,您可以将SS
中的相同值加载为DS
。 ES
寄存器不需要加载任何特定值,因为只有少数指令隐式使用它(MOVS
,SCAS
,CMPS
)。您可能希望它可以免费用作“额外”临时段寄存器来访问除CS
,DS
或SS
引用的内存区域。
请注意,假设您拥有真正的Intel 8086或80186处理器。如果您实际上只有80286或更高版本的处理器,您只想在实模式下使用,那么起始地址将会有所不同。如果你有某种克隆8086处理器,你应该查阅它的数据表,看看它是否也做了不同的事情。
答案 1 :(得分:2)
在我看来,您在询问将启动代码放在何处。
当您启动机器时,直接退出重置,CS
(代码段)具有此值:
0ffffh
0ffff0h
和IP
(指令指针)的值为00000h
。
添加CS.base
和IP
会给出0ffff0h
的起点。
请注意,这并没有给你留下足够的工作空间 - 在内存耗尽之前只剩下16个字节,但它足以让你远远地跳到你希望放置的地方代码。
答案 2 :(得分:1)
...我已经做了很多谷歌搜索,我无法为我的生活找到8086的操作系统编程的参考...
对于无操作系统,无BIOS的8086编程,您可以将某些BIOS源代码用作有价值的信息源。像这样:
http://bochs.sourceforge.net/cgi-bin/lxr/source/bios/rombios.c#L11661
...
//版权所有(C)2002 MandrakeSoft S.A.
...
//用于Bochs / Plex86 / QEMU仿真环境的ROM BIOS
...
.org 0xfff0 ; Power-up Entry Point jmp 0xf000:post ... post: xor ax, ax ... normal_post: ; case 0: normal startup cli mov ax, #0xfffe mov sp, ax xor ax, ax mov ds, ax mov ss, ax ...
另见:
Combined Volume Set of Intel® 64 and IA-32 Architectures Software Developer’s Manuals
9.1.4首次执行指令
硬件复位后获取并执行的第一条指令位于物理地址
FFFFFFF0H
。该地址比处理器的最高物理地址低16个字节。包含软件初始化代码的EPROM
必须位于此地址...
9.7实地址模式操作的软件初始化
硬件复位后(通过上电或
RESET#
引脚置位),处理器进入实地址模式并开始从物理地址FFFFFFF0H
执行软件初始化代码。软件初始化代码必须首先设置必要的数据结构来处理基本系统功能,例如用于处理中断和异常的实模式IDT
。如果处理器要保持实地址模式 ...如果处理器将以保护模式运行 ...