x86数据段如何在实际操作系统和进程中使用?

时间:2012-10-06 13:14:30

标签: operating-system x86 x86-64 segment

我一直在实模式下编写x86 asm程序(bootloaders),我知道如何使用段,寄存器和类似的东西。

我从调试器看到像OllyDbg和类似的DS寄存器,SS等明显使用..但正常的“类Windows”进程如何使用它们?我知道分段是部分使用的(只是将ring0与ring3分开)并且他们的条目在GDT中,我知道有涉及的分页,这将完全弄乱PDE和PTE的地址,但我不能完全“链接“一切都在一起,并了解哪些数据堆栈额外的细分市场......每个流程都有不同的DS / SS / ES?

2 个答案:

答案 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。