1. 程式人生 > 實用技巧 >棧增長方向及大小端模式

棧增長方向及大小端模式

在計算機系統中,我們是以位元組為單位的,每個地址單元都對應著一個位元組,一個位元組為 8bit。

1.棧增長方向

  • 在記憶體管理中,與棧對應是堆。
  1. 對於堆來講,生長方向是向上的,也就是向著記憶體地址增加的方向;對於棧來講,它的生長方式是向下的,是向著記憶體地址減小的方向增長
  2. 在記憶體中,“堆”和“棧”共用全部的自由空間,只不過各自的起始地址和增長方向不同,它們之間並沒有一個固定的界限,如果在執行時,“堆”和 “棧”增長到發生了相互覆蓋時,稱為“棧堆衝突”,系統肯定垮臺。
    在常見的x86中記憶體中棧的增長方向就是從高地址向低地址增長。
    我們可以通過一些程式碼來判斷棧的增長方向:
#include<stdio.h>  
static int stack_dir;  
static void find_stack_direction (void) 
{  
    static char   *addr = NULL;     
    char    	  dummy;            
 
    if (addr == NULL)  
    {                             
        addr = &dummy;  
 
        find_stack_direction ();    
    }  
    else  
    {		
        if (&dummy > addr)  
            stack_dir = 1;              
        else  
            stack_dir = -1;   
    }			
}  
int main(void)  
{  
    find_stack_direction();  
    if(stack_dir==1)  
        puts("stack grew upward");  
    else  
        puts("stack grew downward");  
    return 0;  
}

find_stack_direction函式使用函式遞迴的方法,第一次進入,由於addr為NULL,所以將字元變數dummy的地址賦值給靜態變數addr,第二次進入,由於靜態變數addr已賦了值,所以進入 "Second entry." 接著,將第二次進入的dummy地址和第一次進入的dummy地址相比較,如果值為正,則堆疊向高地址增長;否則,堆疊向低地址增長。


2.大小端模式

  1. 大端模式:Big-Endian就是高位位元組排放在記憶體的低地址端,低位位元組排放在記憶體的高地址端。
  2. 小端模式:Little-Endian就是低位位元組排放在記憶體的低地址端,高位位元組排放在記憶體的高地址端。

為什麼會有大小端模式之分呢?這是因為在計算機系統中,我們是以位元組為單位的,每個地址單元都對應著一個位元組,一個位元組為 8bit。但是在C語言中除了8bit的char之外,還有16bit的short型,32bit的long型(要看具體的編譯器),另外,對於位數大於 8位的處理器,例如16位或者32位的處理器,由於暫存器寬度大於一個位元組,那麼必然存在著一個如何將多個位元組安排的問題。因此就導致了大端儲存模式和小端儲存模式。例如一個16bit的short型x,在記憶體中的地址為0x0010,x的值為0x1122,那麼0x11為高位元組,0x22為低位元組。對於大端模式,就將0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,剛好相反。我們常用的X86結構是小端模式,而KEIL C51則為大端模式。很多的ARM,DSP都為小端模式。有些ARM處理器還可以由硬體來選擇是大端模式還是小端模式。

  1. 使用指標
int i=1;  
char *p=(char *)&i;  
if(*p==1)    
	printf("Little_endian");    //Little_endian
else
	printf("Big_endian");   	//Big_endian
  1. 使用聯合
// 若處理器是Big_endian的,則返回0;若是Little_endian的,則返回1
int Check_CPU( )
{
   union w
   {  
	int a;
	char b;
   } c;
   c.a = 1;
   return(c.b ==1);
 
}

聯合體union的存放順序是所有成員都從低地址開始存放

部落格