CPU的字节序——大端小端模式详解_cpu大端小端_西飘客的博客-程序员宅基地

技术标签: 原理  

1. 什么是大端,什么是小端:

所谓的大端模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;

所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。

2.为什么会有大小端:

为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

3.大小端在内存中的存放方式举例:

 例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址

0x4000

0x4001

存放内容

0x34

0x12

而在Big-endian模式CPU内存中的存放方式则为:

内存地址

0x4000

0x4001

存放内容

0x12

0x34

32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址

0x4000

0x4001

0x4002

0x4003

存放内容

0x78

0x56

0x34

0x12

而在Big-endian模式CPU内存中的存放方式则为:

内存地址

0x4000

0x4001

0x4002

0x4003

存放内容

0x12

0x34

0x56

0x78

4.如何测试编译器是大端还是小端:

下面这段代码可以用来测试一下你的编译器是大端模式还是小端模式:

#include<stdio.h>

int main()

{

    short int x;

    char x0,x1;

    x=0x1122;

    x0=((char *)&x)[0];  //低地址单元

    x1=((char *)&x)[1];  //高地址单元

    printf("x0=0x%x,x1=0x%x",x0,x1);// 若x0=0x11,则是大端; 若x0=0x22,则是小端......

    return 0;

}

以下是我在dev C++里面运行的结果,从结果来看,dev C++用的是小端模式;

 大小端应用场景:
芯片字节序: 大端,符合阅读习惯;
网元字节序: 小端,ARM大部分是小端;
网络字节序: 大端,规定。

如何确定大小端(union方式)

有些CPU公司用大端(譬如C51单片机);有些CPU用小端(譬如ARM)。(大部分是用小端模式,大端模式的不算多)。于是乎我们写代码时,当不知道当前环境是用大端模式还是小端模式时就需要用代码来检测当前系统的大小端。下面给出用程序判断大小端的两种方法:

#include <stdio.h>
 
// 共用体中很重要的一点:a和b都是从u1的低地址开始存放的。
// 假设u1所在的4字节地址分别是:0、1、2、3的话,那么a自然就是0、1、2、3;
// b所在的地址是0而不是3.
 
union myunion
{
	int a;
	char b;
};
 
// 如果是小端模式则返回1,小端模式则返回0
int is_little_endian(void)
{
	union myunion u1;
	u1.a = 0x12345678;				// 地址0的那个字节内是0x78(小端)或者0x12(大端)
    if(0x78 == u1.b)
        return 1;
    else if(0x12 == u1.b)
	    return 0;
}
 
int is_little_endian2(void)
{
	int a = 0x12345678;
	char b = *((char *)(&a));		// 指针方式其实就是共用体的本质
	if(0x78 == b)
        return 1;
    else if(0x12 == b)
	    return 0;
}
 
 
int main(void)
{
	int i = is_little_endian2();
	//int i = is_little_endian();
	if (i == 1)
	{
		printf("小端模式\n");
	}
	else
	{
		printf("大端模式\n");
	}
	
	return 0;
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/technologyleader/article/details/129752679

智能推荐

python代码——labelme标注的车道线结果(点)转为图森车道线格式_labelme curvelane-程序员宅基地

import cv2import jsonimport numpy as npimport osfrom operator import itemgetterpath = '/home/dell/label/'for json_ in os.listdir(path): with open(os.path.join(path+json_),'r') as f: file_ = json.load(f) coors = file_['shapes'] lane1_y = []_labelme curvelane

201671010430 司昕劼 实验十四 课程学习总结-程序员宅基地

实验十四 课程学习总结项目内容这个作业属于哪个课程(https://www.cnblogs.com/nwnu-daizh/)这个作业的要求在哪里(https://www.cnblogs.com/nwnu-daizh/p/11093584.html)课程学习目标掌握软件项目评审会流程;反思总结课程学习内容。任务2:经历了一个学期的软件工程学习和项目实践,请每..._司昕劼

切换多国语言导致Fragment被回收,出现切换错乱-程序员宅基地

如图所示,切换多国语言之后,由于fragment被回收,再次进入app的时候,切换fragment会错乱,甚至有可能切换完全无效果。在百度google之后,发现只有这个和我现在遇到的问题比较像,但是代码却不是很完善。在切换语言时,activity会被系统回收后重新创建,此时原先依附于该activity的fragment也会被系统destroy掉,但系统会自动创建新的fragment的实例atta

2006年百度之星 复赛第5题 追捕 解法 源代码-程序员宅基地

源代码中有注释,因此不再写思路了。该代码已通过acm.pku.edu.cn测试。/* * common.h * * Created on: 2010-2-6 * Author: edan.deng */#ifndef COMMON_H_#define COMMON_H_#include #include #include #include #include #include using namespace std;#define m

使用 Eclipse 远程调试 Java 应用程序-程序员宅基地

利用 Eclipse IDE 的强大功能远程调试 Java 应用程序在本地计算机上调试 Java 应用程序并不是惟一的选择。学习如何使用构成远程调试的不同连接类型进行远程调试。本文概述了设置远程应用程序调试的特性和示例。Charles Lu, 软件工程师, IBM关闭 [x]Charles Lu 是 IBM Chin

tipask mysql调取dedecms_如何完成dedecms外部数据库调用|跨数据库数据调用_paxzone的博客-程序员宅基地

第1步:打开网站include\taglib文件夹中找到sql.lib.php文件,并直接复制一些此文件出来,并把复制出来的这个文件重命名为mysql.lib.php。注:mysql.lib.php,在模板调用时就是直接 {dede:mysql sql=""} 这样调用,mysql这个名字可任意改,在以后会用到。内容来自dedecms第2步:使用相关软件打开刚刚重命名为mysql.lib.php..._tipask链接数据库的文件是啥

随便推点

计算机组成原理实验 组装实验报告,计算机组成原理实验一实验报告..doc_十九小大麻的博客-程序员宅基地

计算机组成原理实验一实验报告.实验一 运算器实验算术逻辑运算器实验目的:掌握算术逻辑运算器单元ALU(74LS181)的工作原理掌握简单运算器的数据传送通道验算由74LS181等组合逻辑电路组成的运算功能发生器运算功能按给定数据,完成实验指定的算术/逻辑运算实验设备计算机组成原理实验仪一台,排线若干条。实验原理实验中所用的运算器数据通道电路如图1-1所示。CNALU_B…… ..._alu dr1h dr1l dr2h

DEDECMS去掉自动生成首页或栏目后面带的index.html-程序员宅基地

Dede默认生成首页后,首页的链接后面会多出一个index.html。据官方说法这样有利于网站优化。但是这个index.html怎么看都不舒服,而且也不利于seo中主页url的统一。因为我的网站的url用.htaccess转向统一都是www,而带.com结尾的。所以出于不让首页权重分散考虑,同时也是美观考虑,dede首页的index.html还是得去掉好。dede首页去掉index....

C8051F120的串口升级程序应用_c8051f120 flash读写-程序员宅基地

使用C8051F120的串口UART实现对单片机软件的升级。_c8051f120 flash读写

NYOJ 236心急的C小加-程序员宅基地

心急的C小加时间限制:1000 ms | 内存限制:65535 KB难度:4描述C小加有一些木棒,它们的长度和质量都已经知道,需要一个机器处理这些木棒,机器开启的时候需要耗费一个单位的时间,如果第i+1个木棒的重量和长度都大于等于第i个处理的木棒,那么将不会耗费时间,否则需要消耗一个单位的时间。因为急着去约会,C小加想在最短的时间内把木棒处理完,你能告诉

ubuntu下获取显示器edid信息的方法_edid modeline-程序员宅基地

~ $ gtf 1920 1080 60 也可以得到modeline或者read-edid也是一个途径,用法是 ~ $ sudo get-edid | parse-edid或者 xrandr -q 查询, xrandr -s 1920 1080_edid modeline

Android之ActionBar、Tabs、Fragment、ViewPager实现标签页切换并缓存页面-程序员宅基地

感觉 Android 到处都是坑,每个地方都要把人折腾半天。今天来简单说说 Android之ActionBar、Tabs、Fragment、ViewPager 实现标签页切换并缓存页面关于他们的介绍就不多说了,网上到处都是,只说关键的部分:我在开发的时候遇到几个疑难问题,花费大量时间处理,总结如下:1. 关于 Fragment 内部逻辑处理该写在哪个事件回调部分?2. View