我們都知道,記憶體中存儲的是各種變量,各種奇葩東西,不用的變量占用不用的字長,例如在intel X86環境下,一個int占用兩個字
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 |
節,即16位。然後在這16位上用0或1來表示這個int類型的變量到底是什麼數值。那麼這樣就有兩種寫法了,在這16位上是從左往右寫呢,還是從右往左寫呢。這就好比現代人寫字從左往右,古人寫字從右往左。根據這樣兩種不同的寫法,計算機中就産生了兩種模式:小端模式和大端模式。具體來看一個例子:
假設在intel X86環境下,有一個數字,是1539,用二進制就表示為:0000 0110 0000 0011(兩個位元組)
高八位 | 低八位 |
0000 0110 | 0000 0011 |
既然計算機以位元組為機關,如果這裡的一個位元組相當于寫一個漢字的話,那這個1539在計算機内部就相當于要寫兩個漢字。怎麼寫呢,不着急,先介紹 小端模式:按照從低位址到高位址的順序,依次存放資料的低位元組到高位元組。
高八位 | 低八位 | |
小端模式: | 0000 0110 | 0000 0011 |
插入一句:一個數的原數,是高位元組在左,低位元組在右,當然是這樣,因為左邊的權值高,2的次方高。學習本篇的時候,要始終記住吧一個個位元組作為一個個機關,而不要着眼于位。
我這裡高八位标在左邊,低八位标在右邊,很多地方低八位标左,高八位标右,這個其實是完全一樣的,怎麼看得舒服就怎麼寫。
按照定義,低位址放低位元組,高位址放高位元組,是以低八位放1539的低位元組,高八位放1539的高位元組。
接下來是 大端模式:按照從低位址到高位址的順序,依次存放資料的高位元組到低位元組。
高八位 | 低八位 | |
大端模式: | 0000 0011 | 0000 0110 |
現在再回頭看看,不過就是正着寫反着寫而已。╮(╯_╰)╭
一般來說,x86 系列 CPU 都是小端模式的位元組序,PowerPC 通常是大端模式位元組序,還有的CPU能通過跳線來設定CPU工作于小端模式還是大端模式模式。基本上要考察都是intel x86 x64環境,都是小端模式,不會那麼坑考冷門的大端模式。。
練習:
0x1234abcd低位址 高位址
小端模式:0xcd 0xab 0x34 0x12
大端模式:0x12 0x34 0xab 0xcd
寫出下列程式的執行結果#include<stdio.h>
main()
{
char *sz = "0123456789";
int *p = (int*)sz;
printf("%x\n",*++p);
}
答案是37363534
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 |
int *p = (int*)sz; 這句話的意思是說把這塊記憶體當做int來對待。可以這樣了解,資料就在記憶體中擺着,就看你當成什麼來用了。
不管32位還是64位,int都占四個位元組,printf那邊有個++p,這個p是int型的指針,是以按照int的大小走四個位元組
即現在p指向的是:
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 | 0x38 | 0x39 |
這塊記憶體區域。還記得嗎,用的是小端模式,那這個int變量該怎麼寫?
很明顯是:0x37363534(低位址存低位元組)
是以用%X輸出的話就看到了37363534這個結果了。
寫出下列程式執行結果int a = 0x12345678;
char *p = (char*)(&a);
printf("%x\n",*(p+1));
答案是0x56
判斷計算機是大端還是小端:
int i=1;
char *p=(char *)&i;
if(*p==1)
printf("小端模式");
else // (*p == 0)
printf("大端模式");