IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 大端与小端 -> 正文阅读

[嵌入式]大端与小端

一.大小端介绍

“大端”和“小端”表示多字节值的哪一端存储在该值的起始地址处。小端存储在起始地址处,即是小短字节序;大端存储在起始地址处,即是大端字节序。

大端存储模式:数据的低位保存在内存中的高地址中,数据的高位保存在内存中的低地址中;
小端存储模式:数据的低位保存在内存中的低地址中,数据的高位保存在内存中的高地址中;(STM32属于小端模式)

常用的x86结构是小端模式,而keil C51则为大端模式,很多的arm、dsp都为小端模式,有些arm处理器还可以由硬件来选择是大端模式还是小端模式。

int a=1;//一个int占4字节

在这里插入图片描述

二.为什么会有大小端存储模式

1.cpu和编译器不同

在计算机系统中,我们是以字节为单位的,每个字节都对应着一个地址单元,但是在C语言中除了8bit的char之外,还有16bit的short型、32bit的long型(要看具体的编译器)。另外,对于位数大于8位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题,因此,就导致了大端存储模式和小端存储模式。

2.网络字节序

网络上传输的数据都是字节流。对于一个多字节数值,在进行网络传输的时候,先传递哪个字节,也就是说,当接收端收到第一个字节的时候,它将这个字节作为高字节还是低字节来处理,是一个比较又意义的问题。
UDP/TCP/IP协议规定:把接收到的第一个字节当作高位字节看待,这就要求发送端发送的第一个字节是高位字节,而在发送端发送数据时,发送的第一个字节是该数值在内存中的起始地址处对应的那个字节,也就是说,该数值在内存中的起始地址处对应的那个字节就是要发送的第一个高位字节。由此可见,多字节数值在发送之前,在内存中是以大端法存放的。所以说,网络字节序是大端字节序。

三.如何判断CPU使用大端存储还是小端存储

1.类型降低

#include<stdio.h>

int main(void)
{
    short int  a = 0x1234;
    unsigned char b=a;
    printf("%xH\n",b);//34H

}

2.使用指针,类型强转

#include<stdio.h>
int main(void)
{
	short a = 0xff00;
	char* b = (char*)&a;
	if (*b == 0xff)
	{
		printf( "大端");
	}
	else
	{
		printf( "小端");
	}
    return 0;
}

3.采用共用体

#include<stdio.h>
int checkCPU()
{
    union w
    {
        int a;
        char b;
    }c;
    c.a = 1;
    return (c.b == 1);
}
int main(void)
{
   if (checkCPU())
        printf("小端\n");
   else
        printf("大端\n");
}

联合体union的存放顺序是所有成员都从低地址开始存放。如果处理器是大端存储模式,则c.b=0,checkCPU()函数返回0。

四.应用实列

#include<stdio.h>

int main(void)
{
    //sizeof(unsigned short)=2
    //sizeof(struct mybitfields)=2
    //sizeof(short)=2
    //sizeof(test)=2
	struct mybitfields
	{
		unsigned short a:4;
		unsigned short b:5;
		unsigned short c:7;
	};
	struct mybitfields test;
	int i;
	test.a = 2;
	test.b = 3;
	test.c = 0;
	i = *((short  *)&test);
	printf("%d\n",i);
	
	return 0;

}

上例的声明方式是把一个short(也就是一块16位内存)分成三部分,各部分的大小分别是4位、5位、7位,赋值语句i = *((short *)&test);就是把上面的16位内存转换成short类型进行解释。变量a的二进制表示为0000000000000010,取其低四位是0010;变量b的二进制表示为0000000000000011,取其低五位是00011;变量c的二进制表示为0000000000000000,取其低七位是0000000。所以合成后得到0000000000110010,即十进制50。

五.如何进行大小端的转换

#include<stdio.h>

//int型
int swapInt32(int intvalue)
{
   int temp = 0;
   temp = ((intvalue & 0x000000FF) << 24)|
          ((intvalue & 0x0000FF00) << 8) |
          ((intvalue & 0x00FF0000) >> 8) |
          ((intvalue & 0xFF000000) >> 24) ;

    return temp;
}

//unsigned short型
unsigned short swapshort16(unsigned short shortvalue)
{
    return ((shortvalue & 0x00FF) << 8) | ((shortvalue & 0xFF00) >> 8);

}

//float型
float swapfloat32(float floatvalue)
{
    typedef union SWAP_UNION
    {
        float unionFloat;
        int unionInt;
    }SWAP_UNION;

    SWAP_UNION swapUnion;
    swapUnion.unionFloat = floatvalue;
    swapUnion.unionInt=swapInt32(swapUnion.unionInt);

}

//double型
void swapdouble64(unsigned char * pin , unsigned char *pout)
{
    for (int i=0; i < 8; i++ )
    {
        pout[7-i] = pin[i];
    }
}
int main(void)
{
    unsigned short x=0x12;
    unsigned short y=swapshort16(x);
    printf("%xH\r\n",y);
    return 0;
}

六.绝对地址相关

1.对绝对地址赋值

*unsigned int *0x100000 = 1234;

2.让程序跳转到绝对地址0x100000去执行

2.1 将0x100000强制转换成函数指针

( void (*)() )0x100000

2.2 再调用它

* ( ( void (*)() )0x100000 ) ();

用typedef可以更直观些

typedef void(*)() voidFuncPtr;
*((voidFuncPtr)0x100000)();
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 00:44:29  更:2022-09-21 00:47:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 2:15:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计