棧增長方向及大小端模式
阿新 • • 發佈:2020-08-12
在計算機系統中,我們是以位元組為單位的,每個地址單元都對應著一個位元組,一個位元組為 8bit。
1.棧增長方向
- 在記憶體管理中,與棧對應是堆。
- 對於堆來講,生長方向是向上的,也就是向著記憶體地址增加的方向;對於棧來講,它的生長方式是向下的,是向著記憶體地址減小的方向增長。
- 在記憶體中,“堆”和“棧”共用全部的自由空間,只不過各自的起始地址和增長方向不同,它們之間並沒有一個固定的界限,如果在執行時,“堆”和 “棧”增長到發生了相互覆蓋時,稱為“棧堆衝突”,系統肯定垮臺。
在常見的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.大小端模式
- 大端模式:Big-Endian就是高位位元組排放在記憶體的低地址端,低位位元組排放在記憶體的高地址端。
- 小端模式: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處理器還可以由硬體來選擇是大端模式還是小端模式。
- 使用指標
int i=1;
char *p=(char *)&i;
if(*p==1)
printf("Little_endian"); //Little_endian
else
printf("Big_endian"); //Big_endian
- 使用聯合
// 若處理器是Big_endian的,則返回0;若是Little_endian的,則返回1
int Check_CPU( )
{
union w
{
int a;
char b;
} c;
c.a = 1;
return(c.b ==1);
}
聯合體union的存放順序是所有成員都從低地址開始存放