问答题 嵌入式编程中,什么是大端?什么是小端
【正确答案】
【答案解析】采用小端模式的CPU对操作数的存放方式是从低字节到高字节,而大端模式对操作数的存放方式是从高字节到低字节。例如,16位宽的数0x1234在小端模式CPU内存中的存放方式(假设从地址0x4000开始存放)见下表1,而在大端模式CPU内存中的存放方式见表2。
表1 0x1234在小端模式CPU内存中的存放方式
内存地址 存放内容
0x4000 0x34
0x4001 0x12
表2 0x1234在大端模式CPU内存中的存放方式
内存地址 内存内容
0x4000 0x12
0x4001 0x34
32位宽的数0x12345678在小端模式CPU内存中的存放方式(假设从地址0x4000开始存放)见表3,而在大端模式CPU内存中的存放方式见表4。
表3 0x12345678在小端模式CPU内存中的存放方式
内存地址 存放内容
0x4000 0x78
0x4001 0x56
0x4002 0x34
0x4003 0x12
表4 0x12345678在大端模式CPU内存中的存放方式
内存地址 存放内容
0x4000 0x12
0x4001 0x34
0x4002 0x56
0x4003 0x78
以如下程序为例。
#include<stio.h>
struct mybitfields
{
unsigned short a:4;
unsigned short b:5;
unsigned short c:7;
}test;
int main()
{
int i;
test.a=2;
test.b=3;
test.c=0;
i=*((short*)&test);
printf("%d/n",i);
return 0;
}
程序输出结果:
50
上例中sizeof(test)=2,上例的声明方式是把一个short(也就是一块16位内存)分成3部分,各部分的大小分别是4位、5位、7位,赋值语句i=*((short*)&test)就是把上面的16位内存转换成short类型进行解释。
变量a的二进制表示为0000000000000010,取其低四位是0010。变量b的二进制表示为0000000000000011,取其低五位是00011。变量c的二进制表示为0000000000000000,取其低七位是0000000。
x86机是小端(修改分区表时要注意)模式,单片机一般为大端模式。小端一般是低位字节在高位字节的前面,也就是低位在内存地址低的一端,可以这样记(小端→低位→在前→与正常逻辑顺序相反),所以合成后得到0000000000110010,即十进制的50。
程序示例如下:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main()
{
unsigned int uiVa1_1=0x12345678;
unsigned int uiVa1_2=0;
unsigned char aucVal[4]={0x12, 0x34, 0x56, 0x78};
unsigned short usVa1_1=0;
unsigned short usVa1_2=0;
memcpy(&uiVa1_2, aucVa1, sizeof(uiVa1_2));
usVa1_1=(unsigned short)uiVa1_1;∥在这儿截断,都取得的是低位
usVa1_2=(unsigned short)uiVa1_2;∥在这儿截断
printf("usVa1_1:%x/n",usVa1_1);∥这儿又转化回来
printf("usVa1_2:%x/n",usVa1_2);∥这边又转化回来
return 0;
}
小端模式是低地址存放低字节,高地址存放高字节,结构如图所示。