Makale numarası: 132005 - Son Gözden Geçirme: 06 Kasım 1999 Cumartesi - Gözden geçirme: 1.0

DOCERR: AllocSelector & FreeSelector belgeleri tamamlanmadı

Sistem İpucuBu makale, kullandığınızdan farklı bir işletim sistemine yöneliktir. Sizinle ilgili olmayabilecek makale içeriği devre dışı bırakıldı.

Bu Sayfada

Hepsini aç | Hepsini kapa

Özet

AllocSelector ve FreeSelector işlevleri için <a2>Windows</a2> SDK belgelerinde bunlar ayırmak ve birden çok seçiciler serbest olduğunu bahsetmek değil. Her işlev, kendisine geçirilen Seçici (uzunluk) sınırını ayırmak veya serbest kaç seçiciler belirlemek için kullanır. Bu makalede, bir veya daha fazla seçiciler AllocSelector'nasıl ayırır ve nasıl FreeSelector seçiciler serbest bırakmalar açıklanır. Bu iki işlev doğru olarak kullanmak için ne bilmelidir de açıklanır. Belgeleri, bu makalede verilen tüm bilgileri içermelidir.

Daha fazla bilgi

AllocSelector (UINT uSelector)

AllocSelector(UINT uSelector) döşenmiş seçiciler dizisi veya yeni bir Seçici ayırır ve temel adresi, <a1>sınır</a1> (uzunluk) ve erişim hakları uSelector için yeni olan selector(s) kopyalar. USelector sınırı 64 K'değerine eşit veya küçükse, tek bir Seçici tahsis edilir. USelector sınırı 64 K'dan büyükse, döşenmiş seçiciler dizisi her Seçici uSelector sınırı 64 K bölümünü işaret şekilde tahsis edilir.

USelector null (BOş) olduğunda, AllocSelector tek, tam olarak başlatılmamış bir Seçici ayırır. Seçiciyi, taban adresi, <a1>sınır</a1> (uzunluk) ve erişim hakları ayarlanıncaya kadar kullanılamaz. Erişim hakları unitialized bir seçici kümesi için <a0></a0>, DOS korumalı modu arabirimi (DPMI) tanımlayıcısı erişim hakları ayarlama (0x09) işlevini çağırmalısınız. Ayrıca, Seçici'nın tablo bit ve ayrıcalık bit seçicisini en düşük sıra üç bitlik ayarlamak için Bit düzey VEYA maskesi 0x0007 kullanarak ayarlamanız gerekir.

Yeni oluşturulan seçicisini ait Erişim Denetim bitlerinin AllocSelector kümesi izin daha kolaydır çünkü başlatılmamış bir Seçici ayrılırken yerine, varolan bir Seçici kopyalamalısınız. Varolan bir seçici bir kopyasını oluşturduktan sonra istediğiniz konuma gelin yapmaları için SetSelectorLimit ve SetSelectorBase kullanın.

Sistem değil izlemek veya otomatik olarak yönetmek için AllocSelector tarafından ayrılan seçiciler tarafından FreeSelector serbest gerekir.

FreeSelector (UINT uSelector)

FreeSelector(UINT uSelector) veya tek bir Seçici hem de döşenmiş seçiciler uSelector sınırına göre bir dizi boşaltır. USelector sınırı 64 K her bölümü için bir Seçici boşaltır. Seçici veya döşenmiş seçiciler serbest bir dizi önceden AllocSelector tarafından ayrılmış olan gerekir. Ayrıca, uSelector sınırını seçicisini AllocSelector çağrısında parametre olarak kullanılan ile aynı olması gerekir.

Döşenmiş seçicileri örnek dizisi

Döşenmiş seçiciler örnek dizisi bu (AllocSelector için geçirilen seçicisini 256 K sınırı olduğunu varsayarak gibi) görüneceğini:
  Sel 1     Sel 2      Sel 3      Sel 4

   0         64K       128K       192K       256K
   +----------+----------+----------+----------+
   |          |          |          |          |
   +----------+----------+----------+----------+
   |          |          |          |--------->| (Limit = 64K)
   |          |          |-------------------->| (Limit = 128K)
   |          |------------------------------->| (Limit = 192K)
   |------------------------------------------>| (Limit = 256K)
				
taban adresi her ardışık Seçici'nın 64 K önceki Seçici'nın temel adresinden başlar ve sınırı olan 64 K'dan önceki seçicisini bildirimi. Döşenmiş bu seçiciler gerçekten ne yapar yerel tanımlayıcı tablosu (LDT) bitişik olmalarını kapsayacaktır. Örneğin, seçilene 1 değeri 0x97, sonra Sel 2 0x9F olacaktır, seçilene 3 0xA7 olacaktır ve Sel 4 0xAF olacaktır.

Yalnızca 1 Sel, blok çok büyük bir işaretçi oluşturmak için kullanılır. Blok ile art?r?n gibi derleyici Sel 1'den Sel Sel Sel 4 3 2 otomatik olarak geçiş kodu oluşturur. Bu, bu makalenin "Code örneği iki" bölümünde listelenen kodunu gösterir.

Örnek kod bir

Bu örnek, bir veri Seçici ayırmayı gösterir. Birden çok seçiciler kod seçici bir kopyasını ayrılırken ve veri Seçici dönüştürmeden tahsis yoksa emin olmak kodu kesimlerinde 16-bit kodu her zaman küçüktür 64 K, böylece:
     UINT codeSelector, dataSelector;

   _asm {
        mov ax, cs
        mov codeSelector, ax
        }

   dataSelector = AllocSelector(codeSelector);
   if (!dataSelector)
      return NULL;

   // Change dataSelector from a code selector into a data selector
   if (PrestoChangoSelector(codeSelector, dataSelector))
      {
      // Set the desired base address and limit
      SetSelectorBase(dataSelector, dwLinearBase);
      DPMISetSelectorLimit(dataSelector, dwLimit);
      }
   else
      {
      // If you get here, you couldn't change dataSelector so you need
      // to free it because you can't use it as a code selector
      FreeSelector(dataSelector);
      return NULL;
      }

   // You now have a single data selector. Use it, and then free it by
   // calling FreeSelector.
				

Kod iki örnek

Bu örnekte, otomatik olarak bellek için belirtilen bölge işaret eden bir dizi döşenmiş seçiciler ayırmak ve Seçici dizisinden büyük bir işaretçi elde gösterilmiştir:
    // The application creates, uses, and frees a huge pointer here
   char __huge * hpMem;

   hpMem = CreateHugePointer (dwBaseAddress, dwLength);

   // hpMem now points to a region of pre-allocated memory, such
   // as a memory-mapped hardware device's buffer. Use it as you
   // would any pointer.

   FreeHugePointer (hpMem);

// The following three functions show how to allocate an array
// of tiled selectors that point to a specified region of memory.

/*--------------------------------------------------------------
  This function creates a huge pointer with the proper number
  of selectors to access physical memory. The huge pointer may be
  used by C or C++ code. dwLinearBase is a 32-bit linear address,
  and dwLength is the number of bytes that the huge pointer will
  be able to access. This function returns the huge pointer if it
  succeeds, or it returns NULL if it fails.
--------------------------------------------------------------*/ 

void __huge * CreateHugePointer (DWORD dwLinearBase,
                                 DWORD dwLength)
   {
   WORD tempSelector = NULL;
   WORD codeSelector = NULL;
   WORD dataSelector = NULL;
   DWORD dwLimit;

   /*
     A segment's limit is defined as the last accessible offset in
     the segment. Because the limit is the last accessible offset, it
     is the desired length of the segment minus 1. For example, if
     you want a 64K segment, then you need a limit of 0xFFFF, not
     0x10000, because the segment contains byte offsets 0 to 0xFFFF.
     Note that a segment with a limit of 0 is actually a single byte
     in length. Thus, this function considers a length of zero
     invalid.
   */ 
   if (dwLength == 0)
      return NULL;

   dwLimit = dwLength - 1;
   /*
     Allocate a single temporary selector by making a copy of the
     code segment selector and converting the copy to a data
     selector. Code segments are always less than or equal to
     64K in length, so you are guaranteed to get a single temporary
     selector and be sure to free a single selector.

     Once you have the temporary selector, set its base address and
     limit to the desired values, which may be larger than 64K.
     Because the memory must be accessed by 16-bit code, you must
     allocate an array of tiled selectors. The temporary selector is
     used to force AllocSelector to allocate an array of the proper
     number of tiled selectors, each with the proper base and limit.
     Then you can free the single temporary selector.

     If you fail anywhere along the way, clean up whatever has been
     done, and return NULL.
   */ 

   _asm {
        mov ax, cs
        mov codeSelector, ax
        }

   tempSelector = AllocSelector (codeSelector);
   if (!tempSelector)
      return NULL;

   /*
     If you can successfully change the tempSelector into a
     data selector, set its base address and limit to the
     desired base and limit, and then allocate the real selector
     array. Otherwise, prepare to return NULL.

     SetSelectorLimit does not handle the granularity bit of
     selectors properly, which limits its usefulness only to ranges
     of addresses less than 1MB in length. This function calls
     DPMISetSelectorLimit, a function defined below, to overcome
     this limitation and allow you to create arrays of tiled
     selectors that can access more than 1MB.
   */ 
   if (PrestoChangoSelector (codeSelector, tempSelector))
      {
      SetSelectorBase(tempSelector, dwLinearBase);
      DPMISetSelectorLimit(tempSelector, dwLimit);
      dataSelector = AllocSelector(tempSelector);
      }
   else
      dataSelector = NULL;

   // Clean up temp selector
   DPMISetSelectorLimit(tempSelector, 0L);
   FreeSelector(tempSelector);

   // dataSelector will be NULL if it could not be allocated
   // successfully, making this function return NULL.
   return (void __huge *)MAKELONG(0, dataSelector);
   }

/*--------------------------------------------------------------
  This function frees pointers allocated by CreateHugePointer.
  It correctly frees all tiled selectors created to access the
  block of physical memory. It is very important that you call
  this on all pointers created by CreateHugePointer and that you
  do not call this function on pointers allocated by any way
  other than using CreateHugePointer.
--------------------------------------------------------------*/ 

void FreeHugePointer (void __huge * hPtr)
   {
   if (hPtr)
      FreeSelector (HIWORD(hPtr));
   }

/*--------------------------------------------------------------
  This function sets the limit of a selector using DPMI Function
  0008h (Set Segment Limit). This function is necessary if the
  segment size is greater than 1 MB because the Windows
  SetSelectorLimit() API function does not correctly set selector
  limits greater than 1 MB.

  Segments that are larger than 1MB are actually page granular,
  meaning that in the descriptor, the limit field is actually
  stored as the number of 4K pages rather than bytes. When you
  specify a limit greater than 1MB, this function rounds it up
  to the nearest page boundary.

  No matter the size of the segment, this function always accepts
  selector limits in number of bytes, never pages. The conversion
  between bytes and pages is handled internally.

  Note that this function takes a segment limit, which is one less
  than the number of bytes in the segment.
--------------------------------------------------------------*/ 

   BOOL DPMISetSelectorLimit (UINT selector, DWORD dwLimit)
   {
      BOOL bRetVal=TRUE;

   // If the limit is >= 1MB, we need to make the limit a mulitple
   // of the page size or DPMISetSelectorLimit will fail.

      if( dwLimit >= 0x100000 )
         dwLimit |= 0x0FFF;

      __asm
      {
         mov  ax, 0008h
         mov  bx, selector
         mov  cx, word ptr [dwLimit+2]
         mov  dx, word ptr [dwLimit]
         int  31h
         jnc  success
         mov  bRetVal, FALSE
       success:
      }
      return bRetVal;
   }
				

Dört uyarılar için unutmayın

Aşağıdaki öneriler, bu makaledeki kullanırken unutmayın:

  • Seçiciler ayrılırken gerçekte herhangi bir bellek ayırmaması. Yalnızca (bellek önceden ayrılan veya bir bellek eşlemeli bir donanım aygıtı tarafından sağlanan) varolan belleğe erişmek için kullanılan bir işaretçi de oluşturur. Bellek ayrılırken ile ayırma seçiciler karıştırmayın.
  • Seçiciler bu diğer ad (noktasına) Windows tarafından ayrılmış bir bellek bloğu güncelleştirilmemiş bellek bloğu taşınırsa. Bellek bloğu taşınmasını sağlamak için <a0></a0>, GlobalFix üzerinde diğer adlar, bir Seçici oluşturmadan önce aramak. Ancak, bir donanım aygıtı tarafından sağlanan bellek ayrılmış seçicisini işaret varsa, aygıtın bellek Windows tarafından ayrılmış olduğundan GlobalFix çağırmak için gerek yoktur.
  • Windows Bellek Yöneticisi hangi görev, görevi bunları doğru şekilde boşaltır emin olmak gerekir; böylece bu işlevlerle seçiciler tahsis izlemek değil. Özellikle, ayrılan çok daha fazla veya daha az seçiciler boş olduğundan emin olun. Bu makaledeki örnek kod, ayırmak ve bu işlevlerle seçiciler boşaltmak için uygun bir şekilde gösterir.
  • Çok sayıda seçiciler ayrılırken, sınırlı bir kaynağın seçicileri olduğu için önerilmez.

Bu makaledeki bilginin uygulandığı durum:
  • Microsoft Windows Software Development Kit 3.1
Anahtar Kelimeler: 
kbmt kb16bitonly kbdocerr KB132005 KbMttr
Otomatik TercümeOtomatik Tercüme
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir:132005  (http://support.microsoft.com/kb/132005/en-us/ )
Retired KB ArticleKullanım Dışı Bilgi Bankası İçeriği Yasal Uyarı
Bu makale, Microsoft'un artık destek sağlamadığı ürünler ile ilgili olarak yazılmıştır. Bu nedenle, bu makale "olduğu gibi" sağlanmıştır ve bundan sonra güncelleştirilmeyecektir.