做爰视频免费的网站,wordpress 汽车模板下载,wordpress建站教程百科,python培训机构哪家好一文彻底理解大小端和位域
为什么有大小端
人们一直认为大道至简#xff0c;就好像物理学上的世界追求使用一个理论来统一所有的现象。为什么cpu存在大小端之分#xff0c;一言以蔽之#xff0c;这两种模式各有各的优点#xff0c;其各自的优点就是对方的缺点#xff0c…一文彻底理解大小端和位域
为什么有大小端
人们一直认为大道至简就好像物理学上的世界追求使用一个理论来统一所有的现象。为什么cpu存在大小端之分一言以蔽之这两种模式各有各的优点其各自的优点就是对方的缺点正因为两者彼此不分伯仲再加上一些硬件厂商的坚持因此在多字节存储顺序上始终没有一个统一的标准
小端模式优点
内存的低地址处存放低字节所以在强制转换数据时不需要调整字节的内容注解比如把int的4字节强制转换成short的2字节时就直接把int数据存储的前两个字节给short就行因为其前两个字节刚好就是最低的两个字节符合转换逻辑CPU做数值运算时从内存中依顺序依次从低位到高位取数据进行运算直到最后刷新最高位的符号位这样的运算方式会更高效
大端模式优点
符号位在所表示的数据的内存的第一个字节中便于快速判断数据的正负和大小
什么是大小端
高位0x12345678低位大端模式低地址0x12-0x34-0x56-0x78高地址小端模式低地址0x78-0x56-0x34-0x12高地址
小端模式是指数据的高字节保存在内存的高地址中而数据的低字节保存在内存的低地址中。简单的说就是低地址存低位高地址存高位。大端模式是正好相反。
通过代码来记忆
大多数情况下小端机器比较多。我们会经常见到如下代码
uint32_t uiVal 0x11223344;
uint8_t *pucLit (uint8_t *) uiVal;我们只需要记住 *pucLit的值是 0x44 即可。
字节内的bit顺序也有大小端
在 kernel 中的源码有如下定义
struct tcphdr {__be16 source;__be16 dest;__be32 seq;__be32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)__u16 res1:4,doff:4,fin:1,syn:1,rst:1,psh:1,ack:1,urg:1,ece:1,cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)__u16 doff:4,res1:4,cwr:1,ece:1,urg:1,ack:1,psh:1,rst:1,syn:1,fin:1;
#else
#error Adjust your asm/byteorder.h defines
#endif __be16 window;__sum16 check;__be16 urg_ptr;
};这里可以观察到在定义struct tcphdr结构体时使用了宏来区分不同的大小端里面字节内8bit的定义顺序恰好相反。一个字节内res1:4, doff:4,在结构体的定义中位置相反。在小端系统中res1:4 排在前面表示字节的低4bit。
可移植性
为了程序的可移植性不要使用位域的定义方式请使用位运算来解决问题。Linux 这里是为了效率牺牲了可移植性。可见效率和可移植性也是鱼和熊掌不可兼得正如这里的大小端互有优势不可兼得。