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"中为了平息一场关于在消息中字节该以什么样的顺序进行传送的争论而引用了该词。该文中,Cohen非常形象贴切地把支持从一个消息序列的最高位开始传送的那伙人叫做Big-Endians,支持从最低位开始传送的相对应地叫做Little-Endians。此后Endian这个词便随着这篇论文而被广为采用。

上面是信息传输的顺序,而本文想要说的是字节在内存中的存储顺序。

如果高位值存放在内存中低位地址就是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;
}

源码请猛击这里Android Demo。

你可能感兴趣的:(Android)