//这个问题一直我众多不甚清楚的问题之一,今天正好又碰到这个,花一些时间整理下。然后从未解之谜的小本本上划掉【:-D】;
0x01 为什么会有大小端
对于跨越多个字节的程序对象(比如,变量,结构体,程序二进制代码,等),我们必须建立两个统一的规则,用来规范化。
第一:这个对象的地址是什么?
第二:这个对象在存储器中是如何排列这些字节的?
对第一条规则,我们好解决,几乎在所有的机器上,多字节对象的存储为连续的字节顺序,对象的地址为所使用字节中最小的地址。
比如,我们有一个类型为int的变量x地址为0x100,那么这四个字节,将被存储在0x100,0x101,0x102,0x103的位置
对第二个规则,却没有那么好解决了。
一般我们书写字节顺序的自然方法是最高有效位在左边,而最低有效位在右边,比如:
0x12345678
其中0x12是最高位字节,而0x78是最低位字节,如果你在纸上反过来写成0x78563412,别人肯定不会认为这个数值就是0x12345678。这个是大家已经先入为主形成的观念了,所有的人都是这样读数的,所以你只要按照这样来读写就行了。
但是对计算机刚研发出来的时候,并没有自然概念这回事!!!所以,最低字节放在存储器低地址位置和最高字节放在存储器地位置对计算机没有任何影响,这要按照规定来读写就行了。
所以那个时候的计算机科学家就产生了两种不同形式的存储方法,一种是:
小端模式:
最低有效字节放在存储器低地址的位置
大端模式:
最高有效字节放在存储器低地址的位置
如图所示:
0x02 大小端设备判断
一般而言:
x86架构上运行的是小端模式
C51架构上运行的是大端模式
ARM结构上运行的是小端模式
其他没测试,不知道,可以用下面的程序测试。
#include <stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, int len){
int i;
for (i = 0; i < len; i ++){
printf("%p %.2x\n", &start[i], start[i]);
}
printf("\n");
}
void show_int(int x){
show_bytes((byte_pointer) &x, sizeof(int));
}
void show_float(float x){
show_bytes((byte_pointer) &x, sizeof(float));
}
void show_pointer(void *x){
show_bytes((byte_pointer) &x, sizeof(void *));
}
int main(void){
int ival = 0x12345678;
float fval = (float) ival;
int *pval = &ival;
show_int(ival);
show_float(fval);
show_pointer(&ival);
return 0;
}
这个程序是在我的mac系统上运行的,可以看到地址是64bit的,并且是小端模式。最低有效位0x78在存储器低地址位0x7ffee56f17ec上,最高有效位0x12在存储器高地址为0x7ffee56f17ef上。
0x03
end~
评论前必须登录!
注册