c語言內存模型


 

文章一、C語言的內存分配模型

1、程序代碼區:存放函數體的二進制代碼。

2、全局區數據區:全局數據區划分為三個區域。全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。常量數據存放在另一個區域里。這些數據在程序結束后由系統釋放。我們所說的BSS段(bss segment)通常是指用來存放程序中未初始化的全局變量的一塊內存區域。BSS是英文Block Started by Symbol的簡稱。

3、棧區:由編譯器自動分配釋放,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。

4、堆區:一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表,呵呵。

5、命令行參數區:存放命令行參數和環境變量的值。 

關於局部的字符串常量是存放在全局的常量區還是棧區,不同的編譯器有不同的實現。可以通過匯編語言察看一下。不過vc環境下,局部常量就像局部變量一樣存儲於棧中,全局常量、字符常量存儲於文字常量區。TC在常量區。

在linux下:可以通過參數-c來編譯生成匯編文件。如: 
gcc -c *.c 
gcc *.o -Map test.txt -o test.elf 
用文本編輯器查看test.txt文件,你就看到那些bss段,data段,text段等信息了,但是沒有堆棧段相關信息,用objdump命令查看.o文件的反匯編后的信息,或者用gcc -S *.c,查看各個.S文件就明白了。

 

文章二、內存的規划種類 

1)常規內(Conventional Memory)在內存分配表中占用最前面的位置,從0KB到640KB(地址000000H~109FFFFH),共占640KB的容量。因為它在內存的最前面並且在DOS可管理的內存區,我們又稱之為Low Dos Memory(低DOS內存),或稱為基本內存(Base Memory),使用此空間的程序有BIOS、DOS操作系統、外圍設備的驅動程序、中斷向量表、一些常駐的程序、空閑可用的內存空間、以及一般的應用軟件都可在此空間執行。

2)高位內存(UM)是英文Upper Memory的縮寫,是常規內存上面的一層內存(640KB~1024KB)。   

3)高端內存區(HMA)是英文High Memory Area的縮寫。它是1024KB至1088KB之間的64KB內存,管為高端內存區,其地址為100000H~10FFEFH或以上,CPU在實地址模式下以Segment:OFFSET(段地址:偏移量)方式來尋址,其尋址的最大邏輯內存空間為(FFFF:FFFF),即10FFEFH。   

4)EMB是英文Extended Memory Block(擴展內存塊)的縮寫,早期采用的擴充存儲器(EPM)必須遵循EMS規范(如使用EMM386.exe),后來使用的擴展存儲器(EXM)必須遵循XMS規范(如使用Himem.sys)。擴展內存是指1MB以上的內存空間,其地址是從100000H開始,連續不斷向上擴展的內存,擴展內存取決於CPU的尋址能力。

文章三、常規內存函數

申請函數:malloc(),farmalloc(),calloc(),farcalloc(),realloc(),farealloc()
函數名: malloc
功 能: 內存分配函數
用 法: void *malloc(unsigned size);


函數名: farmalloc
功 能: 從遠堆中分配存儲塊
用 法: void far *farmalloc(unsigned long size);


函數名: calloc
功 能: 分配主存儲器
用 法: void *calloc(size_t nelem, size_t elsize);


函數名: farcalloc
功 能: 從遠堆棧中申請空間
用 法: void far *farcalloc( unsigned long units, unsigned ling unitsz );


函數名: realloc
功 能: 重新分配主存
用 法: void *realloc(void *ptr, unsigned newsize);


函數名: farrealloc
功 能: 調整遠堆中的分配塊
用 法: void far *farrealloc( void far *block, unsigned long newsize );


使用函數:memcpy(),memset(),memmove(),movedata()


函數名: memcpy

功 能: 從源source中拷貝n個字節到目標destin中

用 法: void *memcpy(void *destin,void *source,unsigned n);


函數名: memset

功 能: 設置s中的所有字節為ch, s數組的大小由n給定

用 法: void *memset(void *s, char ch, unsigned n);


函數名: memmove

功 能: 移動一塊字節

用 法: void *memmove(void *destin,void *source,unsigned n);


函數名: movedata

功 能: 拷貝字節

用 法: void movedata(int segsrc, int offsrc, int segdest, int offdest, unsigned numbytes);


釋放函數:free(),farfree()


函數名: free

功 能: 釋放已分配的塊

用 法: void free(void *ptr);

函數名: farfree

功 能: 從遠堆中釋放一塊

用 法: void farfree(void);


指針操作函數:MK_FP(),FP_OFF(),FP_SEG()


函數名: MK_FP
功 能: 設置一個遠指針
用 法: void far *MK_FP(unsigned seg, unsigned off);


函數名: FP_OFF
功 能: 獲取遠地址偏移量
用 法: unsigned FP_OFF(void far *farptr);


函數名: FP_SEG
功 能: 獲取遠地址段值
用 法: unsigned FP_SEG(void far *farptr);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM