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.
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) 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.
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.
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.
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;
}
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.
Ö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/
)
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.
Bu makaleyi kullanmak için ne kadar kişisel çaba harcadınız?
Çok az
Az
Orta
Fazla
Çok fazla
Bu bilgiyi geliştirmemiz için nedenleri ve bu konuda neler yapabileceğimizi paylaşın
Teşekkürler! Görüşleriniz, destek içeriğimizi geliştirmemize yardımcı olmak için kullanılmaktadır. Diğer yardım seçenekleri için, lütfen Yardım ve Destek Giriş Sayfasını ziyaret edin.