前言
这个问题也是一个困扰我很久的问题,最近看到了就决定拎出来用自己的理解讲一遍。对应CSAPP的2.1.3章 寻址和字节顺序
我的比喻
就是书上印满了字(计算机里存满了binary的数据,这些数据8bit为1byte地存放,就是有很多个byte,很多个字)。那么我们在读书的时候,究竟是从左往右读呢,还是从右往左读呢?
大端法: 苹果
小端法: 果苹
书上的例子
举一个具体的例子,一个数是 0x 01 23 45 67, 放在地址0x100的地方
地址 | 0x100 | 0x101 | 0x102 | 0x103 |
大端法 | 01 | 23 | 45 | 67 |
小端法 | 67 | 45 | 23 | 01 |
最低有效字节在最前面的方式,叫小端法(little endian), 下面是一个例子
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer a, int len) {
int i;
printf("len=%d\t",len);
for(i=0; i<len; i++) {
printf("%x ", a[i]);
}
printf("\n");
}
int main(int argv, char** argc) {
int x = 12345;
short mx = -x;
int* p = &x;
show_bytes((byte_pointer)&x, sizeof(x)); //len=4 39 30 0 0
show_bytes((byte_pointer)&mx, sizeof(mx)); //len=2 c7 cf
show_bytes((byte_pointer)&p, sizeof(p)); //len=8 ac ad 3d 5a fe 7f 0 0
return 0;
}
上面的代码运行,我的输出是
12345 = 39 30 # bianray = 0011 1001 | 0011 0000
-12345 = c7 cf
这个其实是小端的输出结果,我的机器是小端:12345的binary应该是 0b 0011 0000| 0011 1001
最好配个图
应用
- 反汇编器输出的十六进制 43 0b 20 00 其实是 0x 00 20 0b 43这个地址,要反过来读
- 网络传输二进制数据,要格式一致 (我的话就是,内容就哪些,你怎么解释,要约定好)
- 强制类型转换 show_bytes(byte_pointer x,int len), 用sizeof(xxx)来确定对象使用的字节数。需要理解的是计算机的binary不变,改变数据类型只是改变解释这些bianry, 一个例子就是 把一个有符号的负数,强制转换为无符号数, 0x1101 (-3) ,解释为无符号数是 0x1101(13)
我的是64bit系统,所以地址(指针的sizeof)会为8