我一直在实模式下编写x86 asm程序(bootloaders),我知道如何使用段,寄存器和类似的东西。
我从调试器看到像OllyDbg和类似的DS寄存器,SS等明显使用..但正常的“类Windows”进程如何使用它们?我知道分段是部分使用的(只是将ring0与ring3分开)并且他们的条目在GDT中,我知道有涉及的分页,这将完全弄乱PDE和PTE的地址,但我不能完全“链接“一切都在一起,并了解哪些数据堆栈额外的细分市场......每个流程都有不同的DS / SS / ES?
答案 0 :(得分:1)
通常,在x86保护模式和x86-64长模式下,几乎不使用分段(平面内存模型)。有四个主要的段描述符,每个描述符允许访问整个地址空间:ring0代码,ring0数据,ring3代码,ring3数据。使用分页强制执行内存保护。因此,通常所有过程都被赋予相同的CS,DS,SS,ES值。
请注意,某些操作系统在寻址本地数据时使用FS和GS段,例如TIB in Windows。
值得一提的是,在x86保护模式下,这种行为是可选的,内核可以自由地使用多个段进行内存保护,在x86-64中,长模式分段通常被禁用,操作系统被迫使用平面内存模型(尽管它仍然可以使用FS和GS来寻址本地数据和操作系统结构)。
您可能还想查看有关x86和x86-64架构的宝贵信息来源:Intel Manual 3A(第3.2节应澄清您对分段的所有疑问)
答案 1 :(得分:1)
来自英特尔80386 1986年程序员参考手册:
Figure 5-1. Address Translation Overview
15 0 31 0
LOGICAL ╔═══════════════╗ ╔══════════════════════════════╗
ADDRESS ║ SELECTOR ║ ║ OFFSET ║
╚═══════════╤═══╝ ╚═══╤══════════════════════════╝
v v
╔══════════════════════════════╗
║ SEGMENT TRANSLATION ║
╚══════════════╤═══════════════╝
╔══╧═╗ PAGING ENABLED
║PG ?╟────────────────────┐
╚══╤═╝ │
31 PAGING v DISABLED 0 │
LINEAR ╔═══════════╦═══════════╦═══════════╗ │
ADDRESS ║ DIR ║ PAGE ║ OFFSET ║ │
╚═══════════╩═════╤═════╩═══════════╝ │
v │
╔══════════════════════════════╗ │
║ PAGE TRANSLATION ║ │
╚══════════════╤═══════════════╝ │
│<─────────────────────┘
31 v 0
PHYSICAL ╔══════════════════════════════╗
ADDRESS ║ ║
╚══════════════════════════════╝
Figure 5-2. Segment Translation
15 0 31 0
LOGICAL ╔════════════════╗ ╔═════════════════════════════════════╗
ADDRESS ║ SELECTOR ║ ║ OFFSET ║
╚═══╤═════════╤══╝ ╚═══════════════════╤═════════════════╝
┌──────┘ v │
│ DESCRIPTOR TABLE │
│ ╔════════════╗ │
│ ║ ║ │
│ ║ ║ │
│ ║ ║ │
│ ║ ║ │
│ ╠════════════╣ │
│ ║ SEGMENT ║ BASE ╔═══╗ │
└─>║ DESCRIPTOR ╟──────────────>║ + ║<──────┘
╠════════════╣ ADDRESS ╚═╤═╝
║ ║ │
╚════════════╝ │
v
LINEAR ╔════════════╦═══════════╦══════════════╗
ADDRESS ║ DIR ║ PAGE ║ OFFSET ║
╚════════════╩═══════════╩══════════════╝
在Windows中,大多数时间在大多数进程中DS = ES = SS,并且所有进程共享CS和DS的值。进程可能会更改其段寄存器,但很少需要它,因此您将在大多数情况下看到相同的CS和DS / ES / SS值集。内核使用自己的CS和DS。