#Linux杂记--大端模式和小端模式

#Linux杂记--大端模式和小端模式

引言

       这是一次 C 语言编程中有关内存操作的巨坑记录。


问题

       各位读者可以和我一起来思考以下这段小程序的输出:

int
main(void)
{
	uint32_t p = 0x12345678;
	uint8_t *t1 = (uint8_t *)&p;
	uint8_t *t2 = t1 + 1;
	uint8_t *t3 = t1 + 2;
	uint8_t *t4 = t1 + 3;
	printf("p:%x,t1:%x,t2:%x,t3:%x,t4:%x\n", p, *t1, *t2, *t3, *t4);
}

       以下为程序的输出,各位读者有没有产生什么疑问呢?
       


解惑

       这其实是 大小端模式 之间的区别,简单来说,世界上存在两种 CPU 一种是按照人类正常思维的方式存放数据的 大端模式(Big-Endian):数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。
       还有一种就是有利于计算机处理的方式存放数据的 小端模式(Little-Endian):数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来。
       还有一种 网络字节顺序 同大端模式。
       综上所述,按照大端模式 p 的数据在内存中的存放方式为:

1    2    3    4    5    6    7    8
0001 0010 0011 0100 0101 0110 0111 1000
^         ^         ^         ^
t1        t2        t3        t4

       按照小端模式 p 的数据在内存中的存放方式为:

7    8    5    6    3    4    1    2
0111 1000 0101 0110 0011 0100 0001 0010
^         ^         ^         ^
t1        t2        t3        t4

       这时候大家能理解程序的输出了吧?hhh
       需要注意的是,所有的 Intel 系列和大部分 ARM 系列的 CPU 都是按照小端模式存储的。


补充

       分享一个按照小端模式正常读取数据的函数

/**
 * 从内存中按照小端模式读取数据
 *
 * @param base  要读取的内存首址
 * @param output 输出缓冲区
 * @param size  要读取的字节数
 * @return None
 */
void
read_little_endian(void *base, void *output, size_t size)
{
    size_t i;
    char t[size];
    char *base_ = (char *) base;
    char *output_ = (char *) output;
    for (i = 1; i <= size; i++) {
        t[size - i] = *base_;
        base_ += 1;
    }
    for (i = 0; i < size; i++)
        output_[i] = t[i];
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值