【计算机组成原理系列学习二】大端模式和小端模式
上节计算机组成原理课讲到了大端编址和小端编址。
首先,大端编址(Big-Endian)和小端编址(Little-Endian)是两种字节存储机制,两种字节序。标准的Big-Endian和Little-Endian的定义如下:
a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
一.什么是高低地址端
----------------------- 最高内存地址 0xffffffff
栈底
栈
栈顶
-----------------------
NULL (空洞)
-----------------------
堆
-----------------------
未初始 化的数据
----------------------- 统称数据段
初始化的数据
-----------------------
正 文段(代码段)
----------------------- 最低内存地址 0x00000000
由图可以看出,在内存分布中,栈是向下增长的,而堆是向上增长的。
在栈 上分配一个unsigned char buf[4],那么这个数组变量在栈上是如何布局的呢?看下图:
栈底 (高地址)
----------
buf[3]
buf[2]
buf[1]
buf[0]
----------
栈顶 (低地址)
二.什么是高低字节。
拿0x12345678来说,从高位到低位的字节依次是0x12、0x34、0x56和0x78。
Big-Endian: 低地址存放高位,如下图:
栈底 (高地址)
---------------
buf[3] (0x78) -- 低位
buf[2] (0x56)
buf[1] (0x34)
buf[0] (0x12) -- 高位
---------------
栈顶 (低地址)
Little-Endian: 低地址存放低位,如下图:
栈底 (高地址)
---------------
buf[3] (0x12) -- 高位
buf[2] (0x34)
buf[1] (0x56)
buf[0] (0x78) -- 低位
--------------
栈 顶 (低地址)
三.编写程序测试CPU是大端编址还是小端编址。
方法一:利用union的成员共享内存而且存放顺序是所有成员都从低地址开始存放,可以编写下面的程序:
1 #include<stdio.h> 2 #include<iostream> 3 4 using namespace std; 5 int main() 6 { 7 union 8 { 9 int a; 10 char b; 11 }c; 12 c.a=1; 13 if(c.b==1) 14 { 15 printf("Little Endian.\n"); 16 } 17 else 18 { 19 printf("Big Endian.\n"); 20 } 21 return 0; 22 }
方法二:通过指针类型强制转换并对整型数据首字节赋值,判断该赋值赋给了高位还是低位。
1 #include<stdio.h> 2 3 int main() 4 { 5 short int a=0x1234; 6 char * p=(char*)&a; 7 if(*p==0x12) 8 { 9 printf("Big Endian.\n"); 10 } 11 else 12 { 13 printf("Little Endian.\n"); 14 } 15 return 0; 16 }
经过测试,我的电脑是小端编址,这与上课所学的X86是小端编址,MIPS是大端编址相符。