Basic記憶體管理模式

記憶體的管理與規劃

  CPU內部的記憶空間位便於管理必須加以編號,通常以16進位數編成00000H~FFFFFH,這些稱為記憶位址Memory Address

  一般利用作業系統擔負管理記憶體的任務,而記憶體的管理方法,有一種稱為分節記憶Segmentation的方法。此方法乃是利用作業系統建立一個邏輯性的記憶空間謂相對位址,以所謂記憶窗模式,窗口大小為(節內位址)64K(0-65535),表示一次只可以看到64k的記憶位址區間,此區間稱為節區Segment,更改節區指位器的位址,才可以看到連帶相關64K的記憶體位址資料。
  此種管理記憶體的方法,將記憶位址由節位址與節內位址組成。CPU內部以暫存器register用於存放各節區的起始位址,此稱為節區指位器Segment Pointer,固定指向節區的開頭。而
節內位址乃是以節區指位器為參考點(起算點),又稱為偏移值Offset。此種記憶體表示方法稱為相對位址表示法。故資料在記憶體中的實際(絕對)位址便以如下公式表示:

絕對記憶位址=節區指位器值+節內位址

  吾人可以容易由相對位址計算絕對位址,但是由絕對位址計算相對位址時,卻因為節區指位器的位址無法確定,連帶節內位址亦無法確定,一旦節區指位器改變起始位址,則節內位址亦一併改變,遂導致無法計算相對位址。此為其困難點

節區指位器

  程式載入電腦內部時,為執行上的需要,必須將記憶空間分為程式區,資料區以及堆疊區。程式區用來存放程式的程式碼;資料區存放程式所處理的資料,堆疊區作為程式中斷或呼叫副程式時資料及返回位址的暫存區。遂有以下各種節區指位器:

CS Code sgement pointer 指向程式節區
DS Data segment pointer 指向資料節區
ES Extra segment pointer 指向輔助節區
SS Stack segment pointer 指向堆疊節區

  其中DS與ES有部分區域相重疊


 

記憶體內容的讀取與修改

命令
作用
範例
DEF SEG=n (n=0~65535) 定義目前記憶體可用節offset位址 DEF SEG=&Hff00
data=PEEK(offset) 傳回目前offset位址(1byte)所存資料 PEEK(&H0FF5)
POKE offset,data 將data寫入現行節區內offset的位址內 POKE 6,&H41
offset=VARPTR(variable) 尋找變數variable在記憶體的存放offset K=VARPTR(A%)
address=VARSEG(variable) 尋找變數variable在記憶體的節區位址Segment K=VARSEG(A%)

 

各種資料型別在記憶體內的存放方式

 
GWBasic
Quick Basic
整數資料

以兩個位元存放,程式範例如下所示:

10 DEFINT A
20 a = 1
30 DEF SEG
40 m = VARPTR(a)
50 FOR i = 0 TO 1
60       PRINT m + i, PEEK(m + i)
70 NEXT
80 value = PEEK(m) + PEEK(m + 1) * 256
90 PRINT value

  在此程式中,可以發現,整數資料乃是以2byte存放。亦即如圖所示:

  所以透過varptr函數抓取變數a的記憶體位址m,亦可驗證記憶體存放的整數資料值

與左列模式相同
單精數資料

以MBF(Microsoft Binary Format)浮點數格式存放資料

單精數以4byte存放於記憶體,如下圖所示:

DEF SEG
true = -1: a! = 0 
CLS 
DO WHILE true 
	CLS 
	INPUT "a!=",a!
	m = VARPTR(a!) 
	FOR i = 3 TO 0 STEP -1 
		PRINT m + i, 
	NEXT 
	PRINT
	FOR i = 3 TO 0 STEP -1 
		PRINT PEEK(m + i), 
	NEXT 
	SLEEP 
LOOP

 

以IEEE Format浮點數格式存放

單精數以4byte存放於記憶體,如下圖所示:

[下載實驗程式]

參考文件:Microsoft-Q36068-INFO:IEEE Floating-Point Representation and MS language

字串資料

  在GWBasic中使用3個byte表示一個字串,第一個byte指出字串的長度,其餘兩個byte則指出字串存放的起始位址。所以要得到存放在記憶體中字串的真正值,必須另行運算

字串的存放方式,如下圖所示:


[下載實驗程式]

  在QB中則使用4個byte表示一個字串,第一與第二個byte指出字串的長度,其餘兩個byte則指出字串存放的起始位址。

字串的存放方式,如下圖所示:


[下載實驗程式]

陣列資料

利用以下的程式找出陣列元素的位址
L=VARPTR(A(n))  'L便是陣列A第n個元素之位址

def feg
i=0
dim a(3)
a(0)=1:a(2)=2:a(3)=3
k=varptr(a(0))
for i=0 to 2
	print peek(k+i);
next

如果陣列屬於單精準數陣列,則每個陣列元素佔記憶體空間4 byte。

與左列模式相同