地址計算

地址計算(address computation)是指對指針等的地址進行的一系列計算操作,包括獲取變數地址的不同方法以及有效地址計算等等。

基本介紹

  • 中文名:地址計算
  • 外文名:address computation
  • 套用領域:計算機等
  • 對象:地址
  • 原理:儲存原理
  • 特點:在數據存儲區域
地址計算,獲取變數的地址,運算符法,指針變數,有效地址計算,記憶體地址計算,地址映射關係,變數說明,地址計算方法,

地址計算

地址可 以像整數一樣用作運算的對象。由於地址所表示的是數據所在的存儲區域的第一個位置,計算的結果使得指針變數指在數據存儲區域的第一個位置上。因此,地址的計算是按照與整數的計算不同的方法進行的。
指針變數的運算是根據該變數所指向的數據類型進行的。例如,設有
char *P; int *q;
當執行
++p;++q;
這樣兩個遞增語句時,由於字元型數據的大小是以1個位元組為單位的,因此P被遞增1;而由於整型數據的大小通常是以2個位元組為單位的,因此q被遞增2。同樣地,當執行
p=p+4; q=q+4;
時,指針變數P被加上4,而指針變數q則被加上8。由此可見,設P為指針變數,p+k的意思是由P所指向的數據後的第k個數據的地址,亦即P的值與k*sizeof(*p)之和。

獲取變數的地址

要求得變數的地址,大致有兩種方法。

運算符法

可以在變數前面冠以運算符&。
例如,設有int a;則可用&a來求得變數a的地址。一般說來,該值直到程式運行以前都是未定的。即使程式開始運行了,也未必就有一定的值。可能因運行時的環境不同而取不同的值。因此,幾乎不可以究問一個地址實際上到底取什麼值。

指針變數

有一種指針變數是專門用以表示各種數據的地址的。例如,指向字元型數據地址的指針變數P可以這樣定義:
char *P
同樣,指向整型數據地址的指針變數q可以這樣定義:
int *q;
不用說,可以把表示數據存儲區域的地址賦值給指針變數,此外,也可以考慮指針變數的地址,例如,可以用&q來求指針變數q的地址。可以把該值賦給指針變數,例如,可以把它賦給定義為int **q_P;的指針變數q_P中去。由於指針變數q_P是一個指向一個指向int型數據的指針變數的指針變數,因而其定義中必須用兩個*。
由指針變數所指向的數據(該數據的值被寫在與賦到指針變數中的地址值相同的地址上)是用在指針變數之前冠以運算符*的方法來指定的。
例如,設有char *P;int *q;
那么,*P就是一個由指針變數P所指向的字元型數據,而*q就是一個由指針變數q所指向的整型數據。不過,在使用*P和*q的時候,必須事先把數據實際所在的地址賦給指針變數p,和q。
例如,設有int a, *P
可以用
p=&a把變數a的地址賦給指針變數P。這時,*P=5; a=5;
這樣兩個語句就有了相同的含義。像*P這樣用指針間接地指定數據的方法就叫作間接指定。

有效地址計算

在指令的操作碼後面有mod R/M位元組時,該位元組指定了存儲器運算元的位置,modR/M位元組給出了有效地址的計算過程為:
‘有效地址=段+基地址+(變址木比例因子)+位移量
其中:
位移量:指出了運算元的偏移值,可以使用位元組、字或雙字。
基地址:運算元的偏移量由一個通用暫存器作為基地址變數來指定。
(變址球比例因子)+位移量:這是在靜態數據元素中占2位元組、4位元組或8位元組時對靜態數組變址的一‘種高效方法。由位移量對數組的起始位置定址,變址暫存器存放所需的數組元素的下標,處理器則利用比例因子自動把下標變成變址。

記憶體地址計算

不同系統的記憶體地址計算方式不同,在此以8086系列處理機為例進行說明。
若知道8086系列處理機是如何訪問記憶體的,就容易理解使用不同存儲方式的規則和地址的計算方法。8086用於存放有關處理過程或程式控制信息的暫存器有14個,分成如下幾類:通用暫存器、基數指針和變址暫存器、段暫存器和控制暫存器
8086CPU所有暫存器都是16位(2位元組)。通用暫存器是CPU暫存器中最重要的部分。值都放在其中,進行算術運算,比較和分支(跳轉)指令也放在其中。通用暫存器以兩種方式存取:作為一個16位暫存器,或者作為兩個8位暫存器。
基數指針和變址暫存器相對定址、棧指針和塊區移動指令等提供支持。
段暫存器支持8086記憶體分段。CS暫存器存放當前碼段,DS暫存器存放當前數據段,ES暫存器存放附加段,SS暫存器存放堆疊段。
最後,控制暫存器包括狀態標誌暫存器指令指針暫存器。狀態標誌暫存器存放CPU的狀態,而指令指針暫存器指向CPU下一個要執行的指令。
8086用分段存儲結構,總定址空間為1兆位元組(該系列其它功能更強者,定址空間還要大)。要存取1兆位元組RAM至少要用20位地址。8086處理機系列的20位地址在機器內部用2個字(32位)表示,實際上只用20位。但是在8086處理機上,20位地址分放在兩個暫存器中:一個暫存器放段地址,因此它必須是段暫存器,一個段在RAM中占64K。段的起點正好是16位元組的偶數倍。8086用四個段,即代碼段、數據段、堆疊段和附加段。段內任一位元組的地址叫偏移量。任一位元組20位地址在機器內是段號和偏移量的組合。
要算出段號和偏移量組合所指位元組的實際地址,必須先將段暫存器中內容左移四位,再把偏移量加到移位後的段地址上去。20位地址就是這樣形成的。舉個例子,如果段暫存器內放的是10H,而偏移量是100H,那么,下列步驟說明了實際(物理)地址的計算過程·
段暫存器 t 00000000000 10000(10H)
移位後的段暫存器l 0000000000010000
偏移量 1 0000000100000000(100H)
段+偏移量 t ooooo000001000000000(200H)
如果只存取當前段暫存器中的段內地址,則只要裝入地址的偏移量。若存取的地址不在當前段內,必須把要訪問的地址的段號和偏移量都裝入。
地址在8086中最常用的形式是“段:偏移量”。上面的例子若寫成此種形式就是0010:0100H。同一位元組可用多個“段:偏移量”組合表示。例如,0000:0010和0001:0000是一回事。

地址映射關係

(在此以VGA為例進行說明)在所有的VGA圖形模式下,顯示存儲器與螢幕象素點之間的映射關係都是線性的,即顯示存儲器中的每個象素數據按光柵掃描的順序依次對應於螢幕上的每個象素點。在使用位面技術時,象素在每個位面上各占一個數據位,每位具有相回的地址;在沒有採用位面技術時:一個象素點的多個數據位在顯示存儲器中連續存放,只是在24位色模式下有些特殊。下面描述螢幕上的某一個像素點在顯示存儲器中所處位置的計算方法。

變數說明

螢幕坐標原點為螢幕左上角,向右為X軸的正方向,向下為Y軸的正方向。X,Y象素點在螢幕上的位置;
width——當前解析度下的水平象素數;
Height——當前解析度下的垂直象素數;
BitN——當前色彩模式下每個象素所在顯示存儲器中所占的二進制位數;
PlaneN——當前色彩模式下所具有的位面數,在沒有使用位面技術時,設該數為1;
BitPP——在當前色彩模式下每個象素點在地址空間中所占的二進制位數;
scanLeng——一條掃描線在地址空間中所占用的位元組數;
Page—素點在顯示存儲器中所處的頁;
Offset——-象素點在所處頁中的地址偏移量;
Bit——象素點在所在位元組中所處的位(僅在1 6色模式有用)。
另有兩個在編程中需要考慮的參數:
TotalPage—在當前顯示模式下的總頁數:
smsL一地址空間尺寸(64K)與ScanLeng相除的餘數,當該數等於零時意味著可以整除,該數大於零則意味著不能整除。

地址計算方法

BitPP=BitN/PlaneN
ScanLeng=Width*BitPP/8(不適於24位色模式)
Page=(ScanLeng+Y+X*BitPP/8)/1 00 00H
Offset=(ScanLeng+Y+X*BitPP/8)%1 0000H
Bit=X%8(只在16色模式下需要)
在24位色模式下,如果每個象素點連續存放在顯示存儲器中,這時分頁就必然會出現在某個象素點上,為避免這種情況,在每條掃描線之後空出了若干位元組。在320×200解析度下,每條掃描線占用1024個位元組,其實際只需要960個位元組;在640×480解析度下,每條掃描線占用2 048個位元組,其實際需要1920個位元組。在每條掃描線中,各象素點數據靠前連續存放。在24位色模式下ScanLeng不能通過計算得到,而需要直接取得。
另兩個參數的計算方法如下:
TotalPage=(ScanLeng*Height一1)/1 0000H+1
SmSL=1 0000H%ScanLeng

相關詞條

熱門詞條

聯絡我們