ARM Endian(位元組序)初探
Endian這個詞在有道詞典中這樣描述:名詞,位元組儲存次序,元組排列順序,位元組序
這個單詞的出處是諷刺小說《格利佛遊記》,百度百科上的描述是:
在小人國裡的小人因為非常小(身高6英寸)所以總是碰到一些意想不到的問題。有一次因為對水煮蛋該從大的一端(Big-End)剝開還是小的一端(Little-End)剝開的爭論而引發了一場戰爭,並形成了兩支截然對立的隊伍:支援從大的一端剝開的人Swift就稱作Big-Endians,而支援從小的一端剝開的人就稱作Little-Endians......(字尾ian表明的就是支援某種觀點的人)。
1980年,Danny Cohen在其著名的論文"On Holy Wars and a Plea for Peace"中為了平息一場關於在訊息中
上面是資訊傳輸的順序,而本文想要說的是位元組在記憶體中的儲存順序。
如果高位值存放在記憶體中低位地址就是Big-Endian,如果低位值存放在記憶體中的低位地址就是Little-Endian。
比如:
0x11223344在大端機上是11223344,在小端機上是44332211
通常來說,x86 cpu是Little-Endian。而一般ARM CPU也是Little-Endian。
但是當前常見的開發板使用的處理器比如S3C2410A、S3C2440等都是大小端支援的,可以通過軟體選擇。
那麼如何用程式看當前裝置是什麼位元組序呢?
很多人的做法是使用一個指標:
int x = 1;
if(*(char *)&x == 1)
printf("little-endian\n");
else printf("big-endian\n");
或者結構體:
union w { int a; //4 bytes char b; //1 byte } c; c.a=1; if (c.b==1) printf("It is Little_endian!\n"); else printf("It is Big_endian!\n");
那麼如何在Android中測試呢?下面寫了一個Android NDK Demo。
Endian.java
package com.linc.lib;
public class Endian {
static {
System.loadLibrary("Endian");
}
public static native String getEndian();
}
Endian.c
#include "com_linc_lib_Endian.h"
JNIEXPORT jstring JNICALL Java_com_linc_lib_Endian_getEndian(JNIEnv *env, jclass obj)
{
jclass class = (*env)->FindClass(env, "java/lang/String");
jstring endian;
union w
{
int a; //4 bytes
char b; //1 byte
} c;
c.a=1;
if (c.b==1)
endian=(*env)->NewStringUTF(env,"It is Little_endian!\n");
else
endian=(*env)->NewStringUTF(env,"It is Big_endian!\n");
int x = 1;
if(*(char *)&x == 1)
endian=(*env)->NewStringUTF(env,"It is Little_endian!\n");
else
endian=(*env)->NewStringUTF(env,"It is Big_endian!\n");
return endian;
}