当前位置: 首页 > wzjs >正文

哈尔滨做网站的oeminc关键词采集软件

哈尔滨做网站的oeminc,关键词采集软件,网站 http 状态码返回值 301,阐述网站建设的步骤大小端以及跳转到绝对地址 0x100000 嵌入式编程中的大小端详解一、大端模式与小端模式二、判断当前系统是大端还是小端方法一:指针强制类型转换方法二:使用联合体(union) 三、结构体位段和大小端的影响四、大小端影响内存的 memc…

大小端以及跳转到绝对地址 0x100000

    • 嵌入式编程中的大小端详解
      • 一、大端模式与小端模式
      • 二、判断当前系统是大端还是小端
        • 方法一:指针强制类型转换
        • 方法二:使用联合体(union)
      • 三、结构体位段和大小端的影响
      • 四、大小端影响内存的 memcpy 拷贝效果
      • 五、大小端转换函数
      • 六、总结
    • 跳转到绝对地址 0x100000 的原理与实现
      • 一、为何需要跳转?
      • 二、跳转原理
      • 三、代码实现
      • 四、简化写法
      • 五、Flash 分区结构示意图
      • 六、注意事项
      • 七、小结

嵌入式编程中的大小端详解

在嵌入式编程中,理解大小端是非常重要的,它直接关系到数据在内存中的布局和跨平台通信时的数据解析正确性。


一、大端模式与小端模式

大端模式(Big Endian):高字节存在低地址,低字节存在高地址。
小端模式(Little Endian):低字节存在低地址,高字节存在高地址。

例如:

unsigned int temp = 0x12345678;

假设 temp 的地址是 0x20000010,那么:

  • 大端模式 中,内存排列为:

    • 0x20000010:0x12
    • 0x20000011:0x34
    • 0x20000012:0x56
    • 0x20000013:0x78
  • 小端模式(STM32) 中,内存排列为:

    • 0x20000010:0x78
    • 0x20000011:0x56
    • 0x20000012:0x34
    • 0x20000013:0x12

二、判断当前系统是大端还是小端

方法一:指针强制类型转换
#include <stdio.h>int main() {int num = 1;                          // 定义整型变量 num,值为1char *ptr = (char *)&num;             // 强制转换为字符型指针,查看最低地址的字节内容if (*ptr == 1) {printf("小端模式\n");} else {printf("大端模式\n");}return 0;
}
方法二:使用联合体(union)
#include <stdio.h>union endian_check {int num;char single_byte;                     // 访问低地址的单字节
};int main() {union endian_check check;check.num = 1;                        // 赋值为1(0x00000001)if (check.single_byte == 1) {printf("小端模式\n");} else {printf("大端模式\n");}return 0;
}

三、结构体位段和大小端的影响

#include <stdio.h>struct mybitfields {unsigned short a : 4;     // 4位位段unsigned short b : 5;     // 5位位段unsigned short c : 7;     // 7位位段
} test;int main() {int i;test.a = 2;               // 二进制 0010test.b = 3;               // 二进制 00011test.c = 0;               // 二进制 0000000i = *((short *)&test);   // 强制转换结构体地址为 short* 后解引用printf("%d\n", i);        // 输出为50,实际内存内容:0010 00011 0000000 => 0x32return 0;
}

四、大小端影响内存的 memcpy 拷贝效果

#include <stdlib.h>
#include <stdio.h>
#include <string.h>int main() {unsigned int uiVal_1 = 0x12345678;             // 原始整型变量unsigned int uiVal_2 = 0;                      // 存储从字节数组拷贝后的数据unsigned char aucVal[4] = {0x12, 0x34, 0x56, 0x78};  // 定义字节数组unsigned short usVal_1 = 0;unsigned short usVal_2 = 0;memcpy(&uiVal_2, aucVal, sizeof(uiVal_2));     // 把数组内容复制到uiVal_2中usVal_1 = (unsigned short)uiVal_1;              // 截断低16位 => 0x5678usVal_2 = (unsigned short)uiVal_2;              // 拷贝后低16位 => 0x3412 (小端存储顺序)printf("usVal_1: %x\n", usVal_1);               // 输出截断值printf("usVal_2: %x\n", usVal_2);               // 输出截断值return 0;
}

五、大小端转换函数

// 32位整数转换
int swapInt32(int intValue) {int temp = 0;temp = ((intValue & 0x000000FF) << 24) |((intValue & 0x0000FF00) << 8)  |((intValue & 0x00FF0000) >> 8)  |((intValue & 0xFF000000) >> 24);return temp;
}// 16位短整型转换
unsigned short swapShort16(unsigned short shortValue) {return ((shortValue & 0x00FF) << 8) | ((shortValue & 0xFF00) >> 8);
}// 32位浮点数转换(使用联合体)
float swapFloat32(float floatValue) {typedef union {float unionFloat;int unionInt;} SWAP_UNION;SWAP_UNION swapUnion;swapUnion.unionFloat = floatValue;swapUnion.unionInt = swapInt32(swapUnion.unionInt);return swapUnion.unionFloat;
}// 64位双精度浮点数转换(使用指针反转)
void swapDouble64(unsigned char *pIn, unsigned char *pOut) {for (int i = 0; i < 8; i++) {pOut[7 - i] = pIn[i];     // 将输入按字节反转存入输出}
}int main() {int x = 0x12345678;int y = swapInt32(x);         // 调用函数转换大小端printf("%x\r\n", y);           // 输出结果应为 0x78563412return 0;
}

六、总结

  • STM32 采用小端模式。
  • 小端:低位字节存在低地址;大端:高位字节存在低地址。
  • 判断大小端可使用指针、联合体等方法。
  • 位段的使用也会受到大小端的影响。
  • 在多平台数据交换时,必须进行大小端转换,确保数据一致性。

跳转到绝对地址 0x100000 的原理与实现

在嵌入式开发中,程序往往被分布在 Flash 的不同区域。例如,在采用 Bootloader + 主程序(APP)结构的设计中,Bootloader 启动后会跳转到主程序所在的地址开始执行。这种“跳转”就是我们常说的“跳转到绝对地址执行”,下面我们详细介绍其原理与实现方法。


一、为何需要跳转?

常见应用场景包括:

  • Bootloader 启动后跳转到主应用程序执行
  • 多镜像升级系统(A/B 双系统)
  • 不同 Flash 区域运行不同的功能模块

例如,如果主程序被烧录在 Flash 的地址 0x100000(假设起始地址),那么 Bootloader 启动后就需要跳转到这个地址运行主程序。


二、跳转原理

Cortex-M 内核芯片(如 STM32)启动时,会自动读取启动地址前 8 字节:

  • 第 1 个字(偏移 0):主堆栈指针初始值(MSP)
  • 第 2 个字(偏移 4):程序入口地址(Reset_Handler)

因此,跳转前必须:

  1. 设置新的 MSP 值为 *(uint32_t*)0x100000
  2. 设置跳转地址为 *(uint32_t*)(0x100000 + 4) 并执行

三、代码实现

推荐使用 typedef 简化函数指针写法:

#include <stdint.h>#define APP_ADDRESS 0x100000  // 目标程序地址typedef void (*pFunction)(void);  // 定义函数指针类型void jump_to_app(void) {__disable_irq();  // 关闭中断,避免干扰uint32_t jump_address = *(volatile uint32_t*)(APP_ADDRESS + 4); // 程序入口地址pFunction JumpToApplication = (pFunction)jump_address;  // 转换成函数指针__set_MSP(*(volatile uint32_t*)APP_ADDRESS);  // 设置主堆栈指针(MSP)JumpToApplication();  // 跳转执行目标程序
}

上述代码完成了从 Bootloader 跳转到主程序的过程。


四、简化写法

((void (*)())0x100000)();  // 将地址当作函数指针并执行

虽然简洁,但不推荐用于 STM32,因为没有设置 MSP主堆栈指针,容易导致系统异常。


五、Flash 分区结构示意图

+------------------------+
| 地址 0x08000000       | → Bootloader
+------------------------+
| 地址 0x08010000       | → APP 主程序(即 0x100000)
+------------------------+
| ......                |

注:部分 STM32 芯片 Flash 起始地址是 0x08000000,此处 0x100000 视具体芯片配置而定。


六、注意事项

  • 跳转地址处必须是有效程序,并具备正确的中断向量表
  • 必须先设置 MSP,否则可能因栈指针错误导致 HardFault
  • 跳转前应关闭中断,避免中断未关闭造成干扰
  • 若使用 FreeRTOS 等 RTOS,需要考虑中断向量重定向问题

七、小结

项目说明
跳转地址比如 0x100000,主程序存放起点
MSP 设置必须从地址读取并设置 __set_MSP()
入口地址*(uint32_t*)(addr + 4)
函数指针跳转把地址强转为函数指针并调用
http://www.dtcms.com/wzjs/352201.html

相关文章:

  • 网站建设与制作外包服务seo优化快排
  • php网站后台反应慢怎么解决网站搭建公司哪家好
  • 在百度怎么建立自己的网站吗百度怎么做自己的网页
  • 怎样做淘宝商品链接导航网站百度竞价广告的位置
  • 哪个网站有适合小学生做的题谷歌seo网络公司
  • 一见钟情 网站域名注册免费
  • 什么做电子书下载网站百度信息流推广平台
  • 企业标志设计图片冯耀宗seo视频教程
  • ui设计最好的培训机构专业放心关键词优化参考价格
  • 南宁网站怎么做seonba最新新闻
  • wordpress如何分类栏seo整站优化哪家好
  • 鹤壁专业做网站多少钱百度平台我的订单查询在哪里
  • wordpress仿站难吗在线工具
  • 北京政府网站建设网站营销外包哪家专业
  • 网站建设中字样图片seo站长网
  • netcore做网站经典软文案例100例
  • 新服务器做网站培训机构加盟
  • 微网站怎么做滚动凡科小程序
  • 做网站怎么买服务器吗数据分析师培训机构推荐
  • 网站建设怎么骗人百度广告大全
  • 韩雪冬模板网站百度搜索引擎官网入口
  • 珠海网站建设案例百度识图在线入口
  • 仪征网站建设腾讯云服务器
  • 源码网站大淘客cms百度移动端排名软件
  • wordpress获取用户的评论品牌seo培训
  • 视频网站如何优化厦门seo搜索排名
  • 自己做的网站怎么查大数据营销精准营销
  • 莆田网站建设平台郑州抖音seo
  • 网站建设活动策划seo推广专员工作内容
  • 深圳市建设行业门户网站百度推广是怎么做的