near指標和far指標
在dos下(實模式)位址是分段的,每一段的長度為64k位元組,剛好是16位(二進位制的十六位)。
near指標的長度是16位的,所以可指向的位址範圍是64k位元組,通常說near指標的定址範圍是64k。
far指標的長度是32位,含有乙個16位的基位址和16位的偏移量,將基位址乘以16後再與偏移量相加,(所以實際上far指標是20位的長度。)即可得到far指標的1m位元組的偏移量。所以far指標的定址範圍是1m位元組,超過了乙個段64k的容量。例如乙個far指標的段位址為0x7000,偏移量為0x1244,則該指標指向位址0x71224.如果乙個far指標的段位址是0x7122,偏移量為0x0004,則該指標也指向位址0x71224。
如果沒有指定乙個指標是near或far,那麼預設是near。所以far指標要顯式指定。far指標工作起來要慢一些,因為每次訪問乙個far指標時,都要將
資料段或程式段的資料交換出來。另外,far指標的運算也比較反常,例如上面講到的far指標指向同乙個位址,但是比較的結果卻不相同。
9、什麼時候使用far指標
當使用小**或小資料儲存模式時,不能編譯乙個有很多**或資料的程式。因為在64k的乙個段中,不能放下所有的**與資料。為了解決這個問題,需要指定以far函式或far指標來使用這部分的空間(64k以外的空間)。許多庫函式就是顯式地指定為far函式的形式。far指標通常和farmalloc()這樣的記憶體分配函式一起使用。
二、遠(far)指標
遠指標不是讓編譯程式把程式資料段位址作為指標的段位址部分,
而是把指標的段位址與指標的偏移量直接存放在指標內。因此,遠指
針是由4 個位元組構成。它可以指向記憶體中的任一目標,可以用於任一
編譯模式,儘管僅在緊湊、大和巨模式下遠指標才是預設的資料指標。
因為遠指標的段位址在指標內,熟悉80x86 組合語言的人都知道,這
意味著每次使用遠指標時都需要重新裝載段暫存器,這顯然會降低速
度。
應該注意:儘管遠指標可以定址記憶體中的任一單元,但它所定址
的目標也不能超過64k 位元組。這是因為,遠指標在增量或減量之類的
算術運算時,也只是偏移量部分參與運算,而段位址保持不變。因此,
當遠指標增量或減量到超過64k位元組段邊界時就出錯。例如: char far *fp=(char far *)0xb800ffff;
fp++; 在指標加1以後,fp將指向b800:0000,而不是所希望的
c800:0000。
此外,在進行指標比較時,far指標還會引起另外一些問題。far
指標是由偏移量和段位址這樣一對16位數來表示的,對於某一實際內
存位址,far指標不是唯一的,例如,far指標1234:0005、1230:0045、
1200:0345、1000:2345、0900:9345等都是代表實際位址12345,這樣
會引起許多麻煩。
第一,為了便於與「空」(null)指標(0000: 0000)進行比較,當
關係操作符「==」和「!=」用於對far 指標進行比較時,比較的是全
部32位。否則,如果只比較16位偏移量,那麼任何偏移量為0 的指標
都將是「空」(null)指標,這顯然不符合一般使用要求。但在進行這
32位比較時,不是按20位實際位址來比較,而是把段位址和偏移量當
作乙個32位無符號長整數來比較。對於上面這個例子,假設這些指標
分別叫作a、b、c、d、e,儘管這5個far 指標指向的都是同一記憶體單
元,但下列表示式運算的結果卻都為「假」,從而得出錯誤的結論:
if(a==b)....
if(b==c)....
if(c==d)....
if(d==e)....
if(a==c)....
if(a==d)....
第二,當用「>」、「>=」,「<」和「<=」關係操作符對指標進
行比較操作時,比較的僅僅是偏移量部分,即按無符號的16位整數進
行比較。因此,對於上面這個例子,下列表示式運算的結果將都為
「真」,也得出錯誤的結論:
if(e>d)....
if(d>c)....
if(c>b)....
if(b>a)....
if(e>a)....
三、巨(huge)指標
只有巨指標才是一般c 語言教科書上所說的指標,它像遠指標也
佔4個位元組。與遠指標的顯著差別是:當增量或減量超過64k位元組段邊
界時,巨指標會自動修正段基址的值。因此,巨指標不但可以定址內
存中的任一區域,而且所定址的資料目標可以超過64k位元組。例如:
char huge *hp=(char huge *)0xb800ffff;
hp++; 在指標加1後,hp將指向c800:0000。但是,巨指標總是比較慢的,
因為編譯必須生成一小段程式對指標進行32位而不是16位的加減運算。
此外,由於huge指標是規則化指標,每乙個實際記憶體位址只乙個
huge指標,所有在指標比較時不會產生錯誤。
四、基(based)指標
前面已經說過,巨指標綜合了近指標和遠指標的優點。像近指標
一樣,基指標只佔兩個位元組,這兩個位元組是位址的偏移量。像遠指標
一樣,基指標可以定址記憶體中的任一區域。近指標的段位址隱含地取
自程式的資料段,遠指標的段位址取自指標本身,基指標的段位址取
法以及基指標的許多技術和應用問題,請見第11章。
五、各類指標之間的轉換
far指標可以強制轉換為near 指標,做法很簡單,拋掉段位址只
保留偏移量。near指標也可以轉換為far指標,turbo c的做法是從相
應的段暫存器中取得段位址。
far指標有時也需要轉換為huge 指標,以便對指標進行比較或做
其它操作。一種方法是通過下面這樣乙個規則化函式: void normalize(void far **p)
near指標,far指標,huge指標
near指標和far指標 在dos下 實模式 位址是分段的,每一段的長度為64k位元組,剛好是16位 二進位制的十六位 near指標的長度是16位的,所以可指向的位址範圍是64k位元組,通常說near指標的定址範圍是64k。far指標的長度是32位,含有乙個16位的基位址和16位的偏移量,將基位址乘...
near指標,far指標,huge指標
near 指標和far 指標 在dos 下 實模式 位址是分段的,每一段的長度為64k 位元組,剛好是16 位 二進位制的十六位 near 指標的長度是16 位的,所以可指向的位址範圍是64k 位元組,通常說near 指標的定址範圍是64k far 指標的長度是32 位,含有乙個16 位的基位址和1...
near指標,far指標,huge指標
near指標和far指標 在dos下 實模式 位址是分段的,每一段的長度為64k位元組,剛好是16位 二進位制的十六位 near指標的長度是16位的,所以可指向的位址範圍是64k位元組,通常說near指標的定址範圍是64k。far指標的長度是32位,含有乙個16位的基位址和16位的偏移量,將基位址乘...