real 模式下访问 4G 地址空间

转自:点击打开链接


在实模式下不受 1M 空间限制访问 4G 空间,实现这个目的仅仅需要一点小“技俩”,这就是某些资料上所说的 big mode




2.1 原理

  real mode -> protected mode -> real mode

  在实模式转化为 protected 模式时,设置好该问 4G 空间的 descriptors,加载进相应的的 selector,而转回 real 模式时,却不改变相应的 selector。



2.2 实现

下面是相应的汇编码片断示例:

  cli
  lgdt gdt32
  mov eax, cr0
  or eax, 0x1
  mov cr0, eax                       /* 开启 protected mode */
  jmp code32                        /* jmp to code32 */
code32:
  mov bx, 0x18
  mov ds, bx
  mov ss, bx
  xor eax, 0x01                    
  mov cr0, eax                      /* 回到 real mode */
  jmp code16                  
code16:
  mov eax, 0x11223344
  mov dword ptr [eax], 0x12345678
    /* 关键代码:real 下写 1M 以上空间代码 */
looo:
  jmp looo                           /* 死循环 */



  开启 protected mode 时,将 32 位的 descriptor 加载到 segment registers 形成 protected 模式执行环境,返回 real 模式却没变回 real 模式的执行环境,仍旧是 protected 模式执行环境。


以下是示例中的 descriptors table:
0x00000000
0x00000000          /* gdt0: null descriptor */
0x0000ffff
0x00cf9e00           /* gdt1: 32 bit code descriptor */
0x0000ffff
0x00009e00         /* gdt2: 16 bit code descriptor */
0x0000ffff
0x00cf9300          /* gdt3:  32 bit data descriptor */
0x0000ffff
0x00009300        /*  gdt4: 16 bit data descriptor */


示例中只用了 gdt1 及 gdt3



2.3  实验

00007c00:    fa                                      ; cli
00007c01:    0f 01 16 f0 7c                   ; lgdt [0x7cf0]
00007c06:    66 0f 20 c0                       ; mov eax, cr0
00007c0a:    80 c8 01                           ; or al, 0x01
00007c0d:    66 0f 22 c0                       ; mov cr0, eax
00007c11:    ea 16 7c 00 08                 ; jmp far 0008:7c16
00007c16:    c6 c3 18                           ; mov bl, 0x18
00007c19:    8e db                               ; mov ds, bx
00007c1b:    8e d3                               ; mov ss, bx
00007c1d:    80 f0 01                           ; xor al, 0x01  
00007c20:    66 0f 22 c0                      ; mov cr0,  eax
00007c24:    eb 00                              ; jmp $+00
00007c26:    b8 44 33 22 11               ; mov eax, 0x11223344
00007c2b:    c7 00 78 56 34 12           ; mov dword ptr [eax], 0x12345678
00007c31:    eb fe                               ; jmp .


  上面这段机器码是我手工翻译的,懒得使用 nasm,而对 nasm 反感,所以就亲自动手了
将它复制到 floppy 映像的 boot 块。

bios 会将 floppy bootsect 加载了 0x7c00 处执行......



然后,使用 bochs 用 floppy 启动。

附上完整的 a.img (可启动的软盘映像)



2.4 结果  
  在 bochs 启动 a.img 是死循环这是正常的,因为程序中结果是死循环。
  用 vmware 加载 floppy 却出现故障启动不了。
  没在真实环境试过。
 
 
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值