1. 大小端问题

目录

  1. 大小端的概念 
  2. java虚拟机如何解决大小端问题
  3. 如何判断当前运行环境大小端
  4. 算法:把一个大端32位无符号数转为小端

1. 大小端的概念

小端(Little-Endian):低字节位排在内存的低地址端,高字节位排在内存的高地址端

大端(Big-Endian):高字节位排在内存的低地址端,低字节位排在内存的高地址端

例如,对于十六进制数 0x01020304,小端存储的内存布局如下:

内存地址0x0050710x0050720x0050730x005074
存储的值0x040x030x020x01

大端存储的内存布局如下:

内存地址0x0050710x0050720x0050730x005074
存储的值0x010x020x030x04

大端存储的方式,更符合人的阅读习惯。

由于不同厂家生产的cpu标准不同,比如Intel的80x86系列芯片使用小端存储的规则,有的芯片则使用大端存储规则,或支持指定存储规则。

2. java虚拟机如何解决大小端问题

对于java字节码,采用的是大端存储规则。JVM可能运行在各种CPU环境下,那么必然会面临大小端的问题。

JVM内部定义了字节序反转方法,例如swap_u4,用来反转4字节的数据。对于涉及大小端的数据,如魔数、版本号等,如果JVM运行在小端机器上,JVM会在读入数据时进行字节序反转。

3. 如何判断当前运行环境大小端

Java内置的实现,见java.nio.Bits 类的静态代码块,如下

static {
        long a = unsafe.allocateMemory(8);
        try {
            unsafe.putLong(a, 0x0102030405060708L);
            byte b = unsafe.getByte(a);
            switch (b) {
            case 0x01: byteOrder = ByteOrder.BIG_ENDIAN;     break;
            case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN;  break;
            default:
                assert false;
                byteOrder = null;
            }
        } finally {
            unsafe.freeMemory(a);
        }
    }

4. 算法:32位无符号数大小端转换

参考linux内核的实现

static inline unsigned int bswap_32(unsigned int v)
{
	return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
		((v & 0xff0000) >> 8) | (v >> 24);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值