字节序、比特序、大端、小端

梗概

本文介绍了字节序和比特序中的大端和小端,不同的cpu架构有不同的内存数据读写方式,但程序的数值计算发生在寄存器上,cpu通过在寄存器和内存的数据传输转换中对用户隐藏了大端小端;数据在网络中发送的时候会统一转成大端,在主机接收的时候根据主机的CPU架构自行转换,这维护了不同CPU架构下的数据通信;但仍有缺陷的是,如果在跨平台的程序中使用了位域,由于涉及到比特序块数据反转问题,需要手动处理。

字节序: 大端数和小端数

大端数(big-endian)和小端数(little-endian)是两种不同的数据存储方式,这两个中文会让人绕晕,从英文上是比较好理解的。

big-endian:大的部分(数的高位)在存储单元的尾部
little-endian:小的部分(数的低位)在存储单元的尾部

来看一张内存图, 从内存单元上来看排列顺序是这样的,也就是从下往上增长,从右往左增长,当一个指针指向一个int型(四内存单元)的变量时,指针的地址是地址最低的内存单元,CPU从内存中取数的时候是永远都是从最低位(右边)开始一个字节一个字节的取,将它放到寄存器中(寄存器永远是符合人类直觉的LE little-endian存储方式, 内存上的大小端存储经过CPU的加载到寄存器时被转换成LE little-endian, 从而隐藏了内存上的大小端),最左边是就是取一个数的尾部.


image.png

所以就很好理解了,对于一个数int a=0x01020304

内存地址 0x00000004 0x00000003 0x00000002 0x00000001
big-endian 04 03 02 01
little-endian 01 02 03 04

而字节序在CPU与程序中的本质是,字节序是在数据的存储字节大于1的时候,从内存加载一个字节到寄存器上的不同加载方式, 但使用数据的时候,无论是读short ,int 还是long long最终真正使用的是寄存器上的le little endian 的值,所以大小端对人是隐藏的,但当你一个一个去看内存的值的时候,就是直接加载到最低位,这时候就不同了。


image.png

验证机器是big-endian还是little-endian

union num{
int temp;
char c[4];
};

int main(){

union num number;
number.temp = 0x01020304;

cout<<int(number.c[3])<<endl; //如果是1则是小端,4是大端
    return 0;
}

网络传输中的字节序

网络中传输的字节序统一为big endian,主机上的数据在send的时候会通过hton进行转换,到接收端recv的时候ntoh恢复回来,如果hton在big endian架构的系统上是一个空宏

比特序

字节序是在数据的存储字节大于1的时候,从内存加载一个字节到寄存器上的不同加载方式。而比特序,则是加载一个8位的bit的时候到寄存器上的不同方式,一般而言比特序和主机的字节序保持一致是大端或者小端


image.png
image.png

网络传输中的比特序和跨平台程序

网络传输过程中,传输协议做了hton的字节序转换,而网卡则会替我们将比特序统一转换到大端,接收端网卡接收的时候根据自己的cpu架构进行转换,对于cpu,内存而言也是不可见的;但是在使用c的位域的时候,会出现问题,对于如下的结构体,

struct A{
     uint16_t first:4;
     uint16_t second:4;
}A;

从小端序传到大端序的主机上,比特序发生的倒序,cpu在读取的进寄存器时候可以解决,但是 first 和 second对应数值的比特块却完全颠倒了,这就需要手动矫正:


image.png

所以在涉及到位域的跨平台设计中常会看到如下内容,如此一来,在不同平台下,就会发生反转

struct A{
#if defined(__LITTLE_ENDIAN_BITFIELD)
     uint16_t first:4;
     uint16_t second:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
     uint16_t second:4;
     uint16_t first:4;
}A;
image.png

具体参考:
https://www.linuxjournal.com/article/6788
https://blog.csdn.net/liuxingen/article/details/45420455/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355