2012-10-06 32 views
3

我一直在實模式下編寫x86 asm程序(bootloaders),我知道如何使用段,寄存器和類似的東西。在實際操作系統和進程中如何使用x86數據段?

我從類似OllyDbg的調試器以及DS寄存器,SS等類似的調試器中看到了......但是正常的「類Windows」過程如何使用它們呢?我知道分段是部分使用的(只是爲了將ring0與ring3分開),並且他們的條目在GDT中,我知道有分頁涉及,並且會使用PDE和PTE完全混淆地址,但我不能「鏈接」 「一切都在一起,並瞭解什麼數據堆棧額外的細節都是關於..每個進程有不同的DS/SS/ES?

+0

如果你'知道如何使用段,寄存器和類似東西',那麼你不能'完全'鏈接'在一起',又不能'理解什麼數據棧額外的段是關於'?你有什麼問題?是不是每個進程都有不同的DS/SS/ES?「? –

+0

我有很多困惑,因爲在真實模式下,您只需使用段+偏移量尋址模式來尋址內存,一旦進入受保護的內存,並隨分頁發生變化。用戶區中的每個進程是否有不同的DS/SS/ES?它在內核模式中改變還是相同? –

回答

1

來自Intel 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。

+0

感謝您的幫助和偉大的ASCII藝術! –

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節應該闡明你對分割所有的疑慮)

+0

謝謝你向我澄清這一點! –

相關問題