IAPX88 可以处理 1 兆字节内存(20 位寻址),现在我的问题是我们如何使用两个 16 位寄存器来制作 20 位地址。请举例说明。
存储单元的物理地址以 1A32H 的形式给出。内存段的起始地址是什么。或者更准确地说,我应该用来访问它的 seg:off 地址。
有人可以逐步解释我如何解决这个问题吗?
在任何地方它都被解释为将寄存器与段绑定/关联的东西,但我想要理解什么是完全绑定的.
我试图在实模式下绘制到屏幕,所以我试图使用分段访问 0xB8000
我的汇编代码是这样的
[BITS 16]
org 0x7c00
begin:
mov ah, 0x01 ; disable cursor
mov ch, 0x3f
int 0x10
mov ch, 0x0000
mov cs, 0xb800
mov ah, 0x0000
mov [cs:ah], ch ; invalid effective address
end:
jmp end
times 510 - ($-$$) db 0
dw 0xaa55
Run Code Online (Sandbox Code Playgroud)
我将如何正确使用分段来解决 0xB8000?
所以我想检查在实模式下是否支持保护模式和长模式。我知道我可以在处于保护模式时检查对长模式的支持,但这需要cpuid我认为我们在实模式下没有的指令(至少在旧处理器中)。
我没有找到任何相关信息。
英特尔开发文档第3卷第9节的摘录
在硬件复位后获取并执行的第一条指令位于物理地址FFFFFFF0H.
该地址比处理器的最高物理地址低16个字节.
包含软件初始化代码的EPROM必须位于此地址.
在实地址模式下,地址FFFFFFF0H超出处理器的1 MB可寻址范围.处理器初始化为该起始地址如下.
CS寄存器有两部分:可见段选择器部分和隐藏的基址部分.
在实地址模式中,基址通常是通过将16位段选择器值向左移位4位以产生20位基址来形成的.但是,在硬件复位期间,CS寄存器中的段选择器加载F000H,基址加载FFFF0000H.因此,通过将基址添加到EIP寄存器中的值(即,FFFF0000 + FFF0H = FFFFFFF0H)来形成起始地址.
我的问题是为什么它在这里使用单词字节时,似乎只对位有意义.假设CPU的物理极限是0xFFFFFFFF然后0xFFFFFFF0是16 bits从该限制,而不是字节远.现在如果英特尔闪存必须包含映射到顶部的每个地址的单字节值,那么我想我们可以调用16位,字节?
我正在寻找PC提供的BIOS中断列表。
为了获得最常见的BIOS调用,可以使用各种公共资源,但是我希望获得PC的所有BIOS调用列表(可能不是非常公开)。
是否有程序可以做到这一点,或者有什么方式可以编写一个(最好是用汇编或C语言编写)?
我的目标是避免BIOS拆卸。我也知道BIOS的底层API相对相似,因此API调用列表也相似。
我正在以实模式x86程序集编写程序,并且正在尝试执行以下操作:
xor %ds, %ds
Run Code Online (Sandbox Code Playgroud)
而不是替代:
mov $0, %ax
mov %ax, %ds
Run Code Online (Sandbox Code Playgroud)
但是,出现汇编错误:
Error: operand type mismatch for `xor'
Run Code Online (Sandbox Code Playgroud)
为什么是这样?有没有办法解决这个问题以减少代码大小?