near指標,far指標,huge指標

2021-08-24 20:04:53 字數 4502 閱讀 6676

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

指標指向同乙個位址,但是比較的結果卻不相同。

什麼時候使用far

指標?

當使用小**或小資料儲存模式時,不能編譯乙個有很多**或資料的程式。因為在64k

的乙個段中,不能放下所有的**與資料。為了解決這個問題,需要指定以far

函式或far

指標來使用這部分的空間(64k

以外的空間)。許多庫函式就是顯式地指定為far

函式的形式。far

指標通常和farmalloc()

這樣的記憶體分配函式一起使用。

far指標是|

的形式。huge

指標也是|

的形式。

因為可以有每個段都是64k

的,可以定址多個段,所以這種指標的定址範圍很大如果你的程式**或者資料超過了64k

就只能用far

指標或huge

指標來操作了。

它們二者也是有區別的!

huge

指標是經過規範過的,可以直接比較大小。不過由於要處理後進行比較,所以運算速度較慢。far

指標不能直接比較大小,但由於只比較偏移量,所以far

指標的運算速度較快。你可以根據需要選用;

一、近(near)指標

近指標是用於不超過64k

位元組的單個資料段或碼段。對於資料指標,在微、小和中編譯模式下產生的資料指標是近指標,因為此時只有乙個不超過64k

位元組的資料段。對於碼(

即函式指標)

指標,在微、小和緊湊編譯模式下產生的碼指標是近指標,因為此時只乙個不超過64k

位元組的碼段。本章將只討論資料指標。近指標是16

位指標,它只含有位址的偏移量部分。為了形成32

位的完整位址,編譯程式一般是反近指標與程式的資料段的段位址組合起來。因為在大部分情況下程式的資料段的段位址是裝在ds

暫存器內,因此一般沒有必要裝載這個暫存器。此外,當用組合語言和c

語言混合程式設計時,組合語言總是假設ds

含有資料目標的位址。雖然近指標占用空間最小,執行速度最快,但它有乙個嚴格的限制,即只能64k

位元組以內的資料,且只能訪問程式的資料段內的資料。如果在小模式下編譯乙個程式,而這個程式企圖增量乙個近指標使之超過第65536

個位元組,則這個近的指標就會復位到0

。下面就是這樣乙個例子:

char _near *p=(char _near *)0xffff;

p++;

由於近指標的這個嚴重限制,所有在比較大或比較複雜的程式中,都無法使用。

二、遠(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)指標

前面已經說過,巨指標綜合了近指標和遠指標的優點。像近指標一樣,基指標只佔兩個位元組,這兩個位元組是位址的偏移量。像遠指標一樣,基指標可以定址記憶體中的任一區域。近指標的段位址隱含地取自程式的資料段,遠指標的段位址取自指標本身,基指標的段位址取法以及基指標的許多技術和應用問題。

五、各類指標之間的轉換

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位的基位址和16位的偏移量,將基位址乘...

near指標,far指標,huge指標

near指標和far指標 在dos下 實模式 位址是分段的,每一段的長度為64k位元組,剛好是16位 二進位制的十六位 near指標的長度是16位的,所以可指向的位址範圍是64k位元組,通常說near指標的定址範圍是64k。far指標的長度是32位,含有乙個16位的基位址和16位的偏移量,將基位址乘...