深入理解计算机--字节顺序

在看深入理解计算机这本神书时看到一个地方挺有意思的。

一个多字节对象在内存中的排列顺序是什么样子的?在几乎所有的机器上多字节对象被存储为连续的字节序列,对象使用的地址为所用字节中的最小地址。例如假设一个32位系统下的int变量x的地址为0x100即&x的值为0x100,那么x的四个字节将会被存储在存储器的0x100、0x101、0x102、0x103位置。

它们的排列顺序主要有两种

小端法(little-endian)

最低有效字节排列在最前面的方式叫做小端法。 比如32位int值为0x0123456,起始地址为0x100,那么在应用小端法的机器中,表示为
地址0x1000x1010x1020x103
67452301
大多数使用intel兼容的处理器的机器都采用小端法

大端法(big-endian)

与小端法相对应,将最高有效字节排列在最前面的方式叫做大端法。还是一样的例子,32位int值为0x0123456,起始地址为0x100,那么在应用大端法的机器中,表示为
地址0x1000x1010x1020x103
01234567
在书上说大多IBM与Sun Microsystems的机器都采用这种规则,不过感觉我是永远也用不上了
还用许多比较新的机器采用双端法(bi-endian),就是可以配置成大端或小端的机器来运行

总结与应用场景

没有技术上的原因选择哪个字节顺序排列,只要一直坚持一种就好了
下面是按字节输出内存中的值代码
#include
    
    
     
     

typedef unsigned char * byte_pointer;

void show_bytes(byte_pointer start,int len)
{
	int i;
	for (i = 0; i < len; i++)
	{
		printf("%.2x ", start[i]);
	}
	printf("\n");
}

void show_int(int x)
{
	show_bytes((byte_pointer)&x,sizeof(x));
}

void show_float(float x)
{
	show_bytes((byte_pointer)&x, sizeof(x));
}

void show_pointer(void *x)
{
	show_bytes((byte_pointer)&x, sizeof(x));
}

    
    
下面是测试函数
void test_show_bytes(int val)
{
	int ival = val;
	float fval = (float)val;
	int *pval = &val;
	show_int(ival);
	show_float(fval);
	show_pointer(pval);
}
调用
test_show_bytes(0x01234567);
可以得到结果
67 45 23 01
b4 a2 91 4b
d4 fb 2d 00


应用场景一  网络数据传输
对于程序员来说选择,机器所使用的字节排列顺序是不可见的,无论为那种排列编程都会得到相同的结果。但是在有些时候字节顺序会成为问题。首先是在不同类型的机器之间通过网络传送二进制数据时,一个常见的问题是当小端法机器产生的数据传输到大端法机器时接受程序里的字节成了反序的。为了避免由于这个原因而产生错误网络程序的代码编写必须遵守已建立的关于字节顺序的规则,以确保发送方机器将他的内部表示转换成网络标准,而接受方将网络标准转化为它的内部表示。

应用场景二 机器码与某些破解工作

在查看和更改机器级代码时需要注意显示的内存地址之类的值可能是以大端法或者小端法排列的。另外在某些破解时也要注意机器采用的是大端法或者小端法,如在安装黑苹果时修改DSDT文件时,里面的值大多使用小端法排列
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值