雅客食品有限公司招聘:内存中字节操作--高低位的问题

来源:百度文库 编辑:九乡新闻网 时间:2024/04/28 03:22:12

这个有点麻烦,首先我们要明确我们人的书写习惯,从左到右,阅读习惯是左边为高位,右边为低位。所以十六进制输出一个字节的时候,比如0xAE,那么A是高4位,E是低四位。我称之为书写高位和书写地位。

然后我们需要理解大端,小端的机器对于内存高位,内存低位的使用。

Big Endian: 书写 高位字节放到内存的低位地址,反之亦然。以太网网络传输字节序, PowerPC, UltraSparc一类的处理器采用大端。

Little Endian: Intel的IA-32架构采用。高位字节放到内存高位地址。记得学X86结构是有一记忆口令:High high, low low。也就是书写高位放在内存高位,书写低位放在内存低位。

所以我的机器上的0xAE在内存中就应该是A放在内存高位,E放在内存低位。换句话说,也就是我们把内存画在纸上,也应该是左边为高位,右边为低位,那么就与书写习惯一模一样了。

插入一点知识,对于位域的操作,我们使用共同体,因为这样方便对位域进行赋值。比如这样的需求,我需要把一个char类型(1个字节)的十六进制打印出来,比如0x0A。但是如果直接用printf打印,前面的0就打印不出来了。所以我期望使用4位打印一次的方式打印出0A。那么我就可以定义这样一个共同体和位域:

typedef struct a
{
unsigned char Low:4;
unsigned char High:4;
}testbit;

typedef union b{
unsigned char c;
testbit t;
} unionb;

使用如下:将unionb ub.c=XXXX;//XXX表示的是0x0A这样一个字节。

然后用printf("%X",ub.t.High);printf("%X ",ub.t.Low);打印出来就是0x0A了。

这里注意位域的结构是先把低字节的赋值,从低到高。对应到书写顺序,就是从右向左书写,从低位开始书写。

另:还有数组的内存存储形式。0下标的地址要小,也就是低一些。1下标的地址要高一些。也就是内存写在纸上都是右边是低位,左边是高位。右边是0下标,左边是1下标。

所以对于一个大整数,我们存储的时候应该把一个大数字的书写高位放在小的下标上,这样打印的时候从小下标打印出来,才是正确的。或者把书写高位就放在大的下标上,打印的时候从大的下标打印即可。

总之内存的操作一定是从低位开始向高位操作的,位域也不例外,都是从低位开始填充的。数组的存储也是0下标的在内存中的低地址空间。但是对于数组如何填,如何使用,跟程序实现有关系,就看你要如何用了。一种是填入数组就按照书写习惯,然后打印从大下标开始打印,一种就是填入的时候颠倒一下,书写高位放在低字节,然后按照从下标0开始打印的顺序打印出来即可。

参考一下C语言的strcpy实现。strcpy(pData_in, "message digest");把message digest放入了数组pData_in中。打印的时候,从数组的0下标开始打印,就出来了正确的message digest,这说明strcpy实现的时候是先把书写高位放入低内存空间的,也就是小下标。我们实现填充程序也可以参照这个标准,直接完成这样一个倒转,这样别人打印的时候习惯都是从小下标开始打印,也就是从内存低位打印,这样其实打印出来的首先是书写高位。

总结,书写高位和地址高位如果画到纸上的话,都在左边,但是我们书写是从左到右,而打印如果从小下标开始,就是从右向左开始打印,操作的顺序与书写顺序是相反的。这种相反我们应该在程序中实现转换,掩盖住,让用户从小下标开始打印的时候感受不到这种颠倒。