>source

컨텍스트

64 비트를 지원하도록 .NET 라이브러리를 업그레이드하려고합니다. 이 라이브러리는 Windows의 다른 프로세스 메모리에서 직접 다양한 작업을 수행합니다. 나는 두 가지 유형 중 하나를 선택해야합니다  (최대 양수 7FFF'FFFF'FFFF'FFFF) 또는 IntPtr  (최대 양수 값 FFFF'FFFF'FFFF'FFFF) 내 메모리 포인터를 처리합니다. 웹에는이 두 가지에 대한 많은 정보가 있습니다. UIntPtr  CLS와 호환되며 대부분의 .NET API는 그에 의존하기 때문에 사실상 동의 한 선택 인 것 같습니다 (ref IntPtr   Marshal 에서 ).

질문

64 비트 프로세스를 열고 할당 된 메모리 영역과 프로세스에로드 된 모듈을 검사하여 InteropServices 를 사용하여 서명되지 않은 포인터를 지원하는 것이 유용한 지 확인했습니다.  (주소>7FFF'FFFF'FFFF'FFFF). 아래 스크린 샷에서 볼 수 있듯이 메모리 주소가 기호를로드하지 않거나 7FFF'FFFF'FFFF 이상으로 메모리를 할당하지 않는 것 같습니다. 그렇게하는 특별한 이유가 있습니까? 경우에 따라 Windows가 해당 값 위에 메모리 영역을 할당 할 수 있습니까?

감사합니다!

UIntPtr
  • 답변 # 1

    Windows에서 각 프로세스는 8TB의 주소 공간 만 가지고 있으므로 사용자 코드의 상한은 0x7FF'FFFF'FFFF입니다

    와이즈 비즈

    상위 248TB는 커널 모드에 속하며 최대 256TB의 주소 공간을 합하며48 비트로 주소가 지정됩니다. 즉, 가능한 가장 높은 양의 주소는 2<47>-1 = 0x7FFF'FFFF'FFFF

    입니다. 와이즈 비즈

    대부분의 최신 x86-64 구현이 48 비트 가상 주소를 사용하기 때문에 중요한 부분은 48 비트입니다

    와이즈 비즈 x64의 사양으로 인해

    The range of virtual addresses that is available to a process is called the virtual address space for the process. Each user-mode process has its own private virtual address space. For a 32-bit process, the virtual address space is usually the 2-gigabyte range 0x00000000 through 0x7FFFFFFF. For a 64-bit process, the virtual address space is the 8-terabyte range 0x000'00000000 through 0x7FF'FFFFFFFF. A range of virtual addresses is sometimes called a range of virtual memory.

    This diagram illustrates some of the key features of virtual address spaces.

    some of the key features of virtual address spaces

    https://docs.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/virtual-address-spaces

    에 항상 맞는 사용자 공간 포인터를 사용할 수 있습니다 . 더 작은 공간에 의존 할 수 없습니다. CPU는 앞으로 더 많은 주소 라인을 얻을 수 있습니다. Windows 8과 Windows 8.1간에이 문제가 발생하면 이전 버전과의 호환성 플래그가 추가되지 않았습니다.

    실제로 x86에는 양의 포인터와 음의 포인터가 있지만

    In 64-bit Windows, the theoretical amount of virtual address space is 2^64 bytes (16 exabytes), but only a small portion of the 16-exabyte range is actually used. The 8-terabyte range from 0x000'00000000 through 0x7FF'FFFFFFFF is used for user space, and portions of the 248-terabyte range from 0xFFFF0800'00000000 through 0xFFFFFFFF'FFFFFFFF are used for system space.

    에 포인터를 저장합니다.  어쨌든

    The original implementation of the AMD64 architecture implemented 40-bit physical addresses and so could address up to 1 TB (240bytes) of RAM. Current implementations of the AMD64 architecture (starting from AMD 10h microarchitecture) extend this to 48-bit physical addresses and therefore can address up to 256 TB of RAM. The architecture permits extending this to 52 bits in the future (limited by the page table entry format); this would allow addressing of up to 4 PB of RAM.

    https://en.wikipedia.org/wiki/X86-64#Architectural_features

    에서 노 맨 랜드 때문에 일했습니다.   IntPtr 의 널 트랩 범위 .

    태그 된 포인터를 사용하려고한다고 생각하지는 않지만 태그가있는 포인터를 수행 할 수있는 유일한 방법은 맨 아래 두 비트입니다.

  • 답변 # 2

    Windows의 경우 최대 가상 메모리 주소는 7FFF'FFFF'FFFF'FFFF입니다. 즉,이 주소 이외의 메모리를 할당 할 수 없습니다. 역사적으로 AMD와 인텔의 첫 64 비트 프로세서 (AMD64 사양에 따라)는 48 비트의 주소 만 지원했습니다. 따라서 한계입니다.

    자세한 내용은 여기를 참조하십시오. http://www.alex-ionescu.com/?p=50 과 https://blogs.technet.microsoft.com/markrussinovich/2008/11/17/pushing-the-limits-of-windows-virtual-memory/

    IntPtr

관련 자료

  • 이전 c++11 - 목록의 끝에없는 템플릿 함수 매개 변수 팩
  • 다음 c# - ASPNET Core 3 미리보기와 함께 Lamar 2를 사용하는 방법은 무엇입니까?