实模式下寻址4G
标签: asm
以下实验均在bochs上进行。因为后来查到有big real mode,便没在真机上进行实验。
0x00 保护模式进入实模式时产生的问题
进行386cpu模式切换练习时,切换回实模式时没有设置合适的选择子,然后系统崩溃,重启。
对照了书上的代码,少了以下代码。
mov ax, SELECTOR_REAL_MODE
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
其中SELECTOR_REAL_MODE
对应的描述符为
LABEL_DESC_REAL_MODE: DESCRIPTOR 0 , 0ffffh , 092h
段的基址为0x0,段长度为0xffff,这与实模式的寻址方式相一致。
0x01 段寄存器高速缓冲区
在i386中,实模式和保护模式有不同的寻址方式。实模式类似于8086,段基址为段寄存器的内容乘0x10,范围固定为0xffff。保护模式则是通过选择子找到段描述符,根据段描述符的内容设置段的基址、范围。
原先我以为实模式和保护模式寻址是没有关系的。但经历过上面的错误,感觉二者之间有联系。保护模式下会将段描述符的内容装入段寄存器高速缓冲器,随后直接对高速缓冲区进行访问。实模式下或许存在类似的机制,不过段描述符的内容是计算出来的:段基址为段寄存器内容乘0x10,范围固定为0xffff。之后也在书上看到了类似的解释。
那么,如果实模式的寻址方式也是直接访问段寄存器高速缓冲区,只要设法修改段的范围,便能在实模式下访问4G内存(使用32位的寄存器作为偏移)。
0x03 验证:写大于0xfffff的地址。
程序流程:进入实模式,将所有段寄存器高速缓冲区设为基址为0,范围为4G,然后退回实模式。在实模式下向ds:0x100000
的内存写入0x12345678。
图1中段寄存器的limit仍为0xffff。
图2中为程序运行结果。ds段寄存器的范围已修改为0xffffffff,写内存成功。
代码如下:
big_real_mode.asm
%include "asm_struct.asm"
%include "usually.asm"
org 100h
xchg bx, bx
jmp start
[section .data]