棧增長方向與大端/小端問題


棧增長和大端/小端問題是和CPU相關的兩個問題。
在內存管理中,與棧對應是堆。對於堆來講,生長方向是向上的,也就是向着內存地址增加的方向;對於棧來講,它的生長方式是向下的,是向着內存地址減小的方向增長。在內存中,“堆”和“棧”共用全部的自由空間,只不過各自的起始地址和增長方向不同,它們之間並沒有一個固定的界限,如果在運行時,“堆”和 “棧”增長到發生了相互覆蓋時,稱為“棧堆沖突”,系統肯定垮台。
在常見的x86中內存中棧的增長方向就是從高地址向低地址增長。
我們可以通過一些代碼來判斷棧的增長方向:
#include<stdio.h>  
static  int stack_dir;  
static  void find_stack_direction ( void)  {  
     static  char   *addr = NULL;    /*  address of first
                                     `dummy', once known 
*/  
     char     dummy;           /*  to get stack address  */  

     if (addr == NULL)  
    {                            /*  initial entry  */  
        addr = &dummy;  

        find_stack_direction ();   /*  recurse once  */  
    }  
     else                           /*  second entry  */  
         if (&dummy > addr)  
            stack_dir =  1;             /*  stack grew upward  */  
         else  
            stack_dir = - 1;            /*  stack grew downward  */  
}  

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地址相比較
如果值為正,則堆棧向高地址增長;否則,堆棧向低地址增長

大端/小端就是Big-Endian/Little-Endian問題
大端:高位字節存在高地址上,低位字節存在低地址上
小端:低位字節存在高地址上,高位字節存在低地址上
有兩種常見的方法來判斷是大端還是小端
方法一:使用指針
int x=1;
if(*(char*)&x==1)
    printf("little-endian\n");
else
    printf("big-endian\n");
方法二:使用聯合
union{
    int i;
    char c;
}x;
x.i=1;
if(x.c==1)
    printf("little-endian\n");
else
    printf("big-endian\n");
下面是一個圖示:
下面的代碼是實現大端和小端整數的轉換:
int chgendian(int x){
    int x2=0;
    char *p=(char*)&x;
    int i=sizeof(int)-1;
    while(i>=0){
        x2|=*p<<(i*8);
        i--;
        p++;
    }
    return x2;
}


 

 

 

 


免責聲明!

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



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