2012-10-06 2 views
3

저는 리얼 모드에서 x86 asm 프로그램 (부트 로더)을 프로그래밍 해왔고 세그먼트, 레지스터 등을 사용하는 방법을 알고 있습니다.실제 운영 체제 및 프로세스에서 x86 데이터 세그먼트는 어떻게 사용됩니까?

OllyDbg와 비슷한 디버거에서 DS 레지스터, SS 등이 사용되는 것을 볼 수 있습니다.하지만 정상적인 "Windows와 유사한"프로세스는 어떻게 사용합니까? 분할이 부분적으로 (ring0과 ring3을 분리하기 위해) 사용되었고 항목이 GDT에 있음을 알고 있습니다. 페이징이 관련되어 있으며 PDE와 PTE를 사용하여 주소를 완전히 엉망으로 만들었지 만 링크가 불가능합니다. "모든 것을 하나로 모으고 추가 데이터 세그먼트 스택에 대한 모든 것을 이해합니다. 각 프로세스마다 다른 DS/SS/ES가 있습니까?

+0

'세그먼트, 레지스터 및 그와 유사한 것들을 사용하는 방법을 알고 있다면'당신이 '함께 묶을 수 없다'는 것이 무엇이며 어떻게하면 여분의 세그먼트가 어떤 데이터 스택인지에 대해 이해할 수 없습니까? '? 질문이 뭐야? 각 프로세스는 다른 DS/SS/ES를 가지고 있습니까? " –

+0

리얼 모드에서는 세그먼트 + 오프셋 주소 지정 모드를 사용하여 페이징으로 변경되는 보호 메모리에서 메모리를 지정하기 때문에 혼란스러워합니다. 사용자 영역의 각 프로세스마다 다른 DS/SS/ES가 있습니까? 커널 모드에서 변경되거나 동일합니까? –

답변

1

(3.2 절은 분할에 대한 모든 의혹을 명확히해야한다) 프로그래머 참조 설명서 1986 :

또한 x86 및 x86-64의 아키텍처에 대한 정보의이 귀중한 소스를 확인 할 수 있습니다

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

도와 주시고 위대한 아스키 아트에 감사드립니다! –

1

일반적으로 x86 보호 모드와 x86-64 긴 모드에서 조각화는 사실상 사용되지 않습니다 (플랫 메모리 모델). 링 오 코드, 링 0 데이터, 링 3 코드, 링 3 데이터라는 전체 주소 공간에 대한 액세스를 허용하는 4 개의 주요 세그먼트 설명자가 있습니다. 메모리 보호는 페이징을 사용하여 시행됩니다. 따라서 일반적으로 모든 프로세스에는 동일한 CS, DS, SS, ES 값이 부여됩니다.

일부 운영 체제는 FS 및 GS 세그먼트를 사용하여 로컬 데이터를 주소 지정합니다 (예 : TIB in Windows).

x86 보호 모드에서 이러한 동작은 선택 사항이며 커널은 메모리 보호를 위해 여러 세그먼트를 자유롭게 사용할 수 있지만 x86-64 긴 모드에서는 일반적으로 세그먼트 화를 사용할 수 없으며 운영 체제는 플랫 메모리를 사용해야합니다 모델 (여전히 로컬 데이터 및 운영 체제 구조의 주소 지정을 위해 FS 및 GS를 사용할 수 있음). Intel Manual 3A 인텔 80386에서

+0

나에게이 점을 분명히 해주셔서 감사합니다! –