大端模式&小端模式、主机序&网络序、入栈地址高低问题
所谓的“大端模式”,是指数据的低位(就是权值较小的后面那几位)保存在内存的高地址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;
所谓的“小端模式”,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
如果将一个32位的整数0x12345678 存放到一个整型变量(int)中,这个整型变量采用大端或者小端模式在内存中的存储由下表所示。为简单起见,本文使用OP0表示一个32位数据的最高字节MSB(Most Significant Byte),使用OP3表示一个32位数据最低字节LSB(Least Significant Byte)。
地址偏移 大端模式 小端模式
0x00 12(OP0) 78(OP3)
0x01 34(OP1) 56(OP2)
0x02 56(OP2) 34(OP1)
0x03 78(OP3) 12(OP0)
小端:较高的有效字节存放在较高的存储器地址,较低的有效字节存放在较低的存储器地址。
大端:较高的有效字节存放在较低的存储器地址,较低的有效字节存放在较高的存储器地址。
采用大小模式对数据进行存放的主要区别在于在存放的字节顺序,大端方式将高位存放在低地址,小端方式将高位存放在高地址。采用大端方式进行数据存放符合人类的正常思维,而采用小端方式进行数据存放利于计算机处理。到目前为止,采用大端或者小端进行数据存放,其孰优孰劣也没有定论。
下面这段代码可以用来测试一下你的编译器是大端模式还是小端模式:
short int x;
char x0,x1;
x=0x1122;
x0=((char*)&x)[0]; //低地址单元
x1=((char*)&x)[1]; //高地址单元
若x0=0x11,则是大端; 若x0=0x22,则是小端......
上面的程序还可以看出,数据寻址时,用的是低位字节的地址
二、主机序&网络序
不同的 CPU 有不同的字节序类型这些字节序是指整数在内存中保存的顺序这个叫做主机序,最常见的有两种:
1、Little endian :将低序字节存储在起始地址
2、Big endian :将高序字节存储在起始地址
网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。
为了进行转换 bsd socket提供了转换的函数 有下面四个:
htons 把unsigned short类型从主机序转换到网络序
htonl 把unsigned long类型从主机序转换到网络序
ntohs 把unsigned short类型从网络序转换到主机序
ntohl 把unsigned long类型从网络序转换到主机序
在使用little endian的系统中,这些函数会把字节序进行转换
在使用big endian类型的系统中,这些函数会定义成空宏
同样,在网络程序开发时,或是跨平台开发时,也应该注意保证只用一种字节序,不然两方的解释不一样就会产生BUG。
注:
1、网络与主机字节转换函数:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)
2、不同的CPU上运行不同的操作系统,字节序也是不同的,参见下表:
处理器 操作系统 字节排序
Alpha 全部 Little endian
HP-PA NT Little endian
HP-PA UNIX Big endian
Intelx86 全部 Little endian <-----x86系统是小端字节序系统
Motorola680x() 全部 Big endian
MIPS NT Little endian
MIPS UNIX Big endian
PowerPC NT Little endian
PowerPC 非NT Big endian <-----PPC系统是大端字节序系统
RS/6000 UNIX Big endian
SPARC UNIX Big endian
IXP1200 ARM核心 全部 Little endian
下面是一个检验本机字节序的简便方法:
//判断本机的字节序
//返回true表为小段序。返回false表示为大段序
bool am_little_endian ()
{
unsigned short i=1;
return (int)*((char *)(&i)) ? true : false;
}
int main()
{
if(am_little_endian())
{
printf("本机字节序为小段序!\n");
}
else
{
printf("本机字节序为大段序!\n");
}
return 0;
}
三、入栈地址高低问题
堆栈是在内存中指定的一段特殊存储区,存起始单元的地址叫栈底,当前存储单元地址叫栈顶,堆栈存储区一旦指定,栈底就固定不变了,而栈顶是随入栈、出栈操作呈动态。而不同机型的堆栈设计,有两种情况:一是每入栈一个数,栈顶地址加1,每出栈一个数,栈顶地址减1,即堆栈区是由内存的低地址向高地址。另一种是每入栈一个数,栈顶地址减1,每出栈一个数,栈顶地址加1,即堆栈区是由内存的高地址向低地址。高地址、低地址是相对而言,即相对地址编码的大小而言。
大端模式&小端模式、主机序&网络序、入栈地址高低问题的更多相关文章
- 【转】如何判断CPU是大端还是小端模式
原文网址:http://blog.csdn.net/ysdaniel/article/details/6617458 如何判断CPU是大端还是小端模式 http://blog.sina.com.cn/ ...
- 转!大端模式&小端模式
大端模式&小端模式 在C语言中除了8位的char型之外,还有16位的short型,32位的long型(要看具体的编译器),对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器 ...
- 判断CPU是大端还是小端模式
在小端模式中,低位字节放在低地址,高位字节放在高地址:在大端模式中,低位字节放在高地址,高位字节放在低地址.big-endian和little-endian,51单片机是典型的大端模式,Intel电脑 ...
- 大端模式、小端模式和C#反转
A.C#大端模式和小端模式. 小端(little-endian)模式:低地址上存放低字节,高地址上存放高字节. 如0x11223344→ byte[] numBytes = new byte[]{ 0 ...
- Linux网络编程1——小端模式与大端模式
数据存储优先顺序的转换 计算机数据存储有两种字节优先顺序:高位字节优先(称为大端模式)和低位字节优先(称为小端模式).内存的低地址存储数据的低字节,高地址存储数据的高字节的方式叫小端模式.内存的高地址 ...
- linux网路编程:字节序(大端、小端、网络、主机)
字节序:就是数据在内存中的存放顺序,也可称之为端模式. 大端模式和小端模式的定义 1) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端. 2) Big-End ...
- 大端模式 VS 小端模式
简单点说,就是字节的存储顺序,如果数据都是单字节的,那怎么存储无所谓了,但是对于多字节数据,比如int,double等,就要考虑存储的顺序了.注意字节序是硬件层面的东西,对于软件来说通常是透明的.再说 ...
- 用C语言,如何判断主机是 大端还是小端(字节序)
所谓大端就是指高位值在内存中放低位地址,所谓小端是指低位值在内存中放低位地址.比如 0x12345678 在大端机上是 12345678,在小端机上是 78564312,而一个主机是大端还是小端要看C ...
- 【C/C++开发】内存对齐(内存中的数据对齐)、大端模式及小端模式
数据对齐,是指数据所在的内存地址必须是该数据长度的整数倍.DWORD数据的内存起始地址能被4除尽,WORD数据的内存起始地址能被2除尽.X86 CPU能直接访问对齐的数据,当它试图访问一个未对齐的数据 ...
随机推荐
- android核心分析--转
http://blog.csdn.net/column/details/androidcore.html http://simon-fu.vicp.cc/?p=999 http://www.uml.o ...
- Linux下串口编程入门
简介: Linux操作系统从一开始就对串行口提供了很好的支持,本文就Linux下的串行口通讯编程进行简单的介绍. 串口简介 串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用.常用 ...
- 杭州网赛 two rabbits (hdu 4745)
算法很简单,问题是,怎么证明,答案是回文序列. 设a,b走的序列按顺时针是: a1 , a2 , a3 , ... , ak b1 , b2 , b3 , ... , bk 考虑端点的2种情况: 1. ...
- FFmpeg缩放swscale详解 <转>
利用ffmpeg进行图像数据格式的转换以及图片的缩放应用中,主要用到了swscale.h文件中的三个函数,分别是: struct SwsContext *sws_getContext(int srcW ...
- pyqt 托盘例子学习
# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' from PyQt4.QtGui import * from PyQ ...
- SQL参数化
本文来自:caodonglin 一.SQL参数化为什么能防注入? 因为执行计划被重用了,所以可以防SQL注入. 下面有两段SQL 正常SQL: 1 select COUNT(1) from C ...
- unity3d 建树篇
今天碰到有人问这个问题,然后我经过一番折腾,找到了方法.例如以下: 有学过Unity3d的同学生都知道我们在对地形拖拉树木等表层时,其树木在我们实例执行中,它们都是能够任其他物体穿过. 这是为什么.相 ...
- 解决angular 与django的冲突
{% block main %} <script type="text/javascript" src="http://cdnjs.cloudflare.com/a ...
- 为项目编写Readme.MD文件
了解一个项目,恐怕首先都是通过其Readme文件了解信息.如果你以为Readme文件都是随便写写的那你就错了.github,oschina git gitcafe的代码托管平台上的项目的Readme. ...
- container宽度
bootstrap:宽度太宽时无需改变container的宽度大小,只需:.row{margin-left: 30px;margin-right: 30px;}