C语言熟练操作内存

关注v-x-公-众-号:【嵌入式基地
后-台-回-复:【电赛】 即可获资料
回复【编程】即可获取
包括有:C、C++、C#、JAVA、Python、JavaScript、PHP、数据库、微信小程序、人工智能、嵌入式、Linux、Unix、QT、物联网、算法导论、大数据等资料

在这里插入图片描述
原文链接 点击查看

嵌入式编程之内存操作

数据指针

在嵌入式系统编程中,经常会对特定的内存单元进行读写操作。在汇编中有对应的MOV指令,而在C/C++以及其他高级语言中基本没有直接操作绝对地址的能力。而在嵌入式系统的实际开发调试过程中,大多情况会借助C语言指针多具备的对绝对地址单元内容的读写能力。
直接使用指针操作内存,主要分为以下几种情况:

  • 某I/O芯片被定位在CPU的存储空间而非I/O空间,而且寄存器对应的是特定的地址
  • 两个CPU之间以双端口RAM进行通信,CPU需要在双端口RAM的特定单元(mail box)书写内容以在对方CPU产生中断。
  • 读写ROM或FLASH的特定单元所烧录的汉字或英文字模
< 在绝对地址0x01写入10
unsigned char *p = (unsigned char *)0x01;
*p = 10;

使用绝对地址时,需要注意指针自增自减的结果取决于指针指向的数据类型。

int *p = (int *)0x01;

p++的结果为:p = p + sizeof(int);p–的结果为:p = p - sizeof(int);
cpu以字节为单位编址,而C语言指针以指向的数据类型长度作为自增自减

函数指针

  • C 语言中函数名直接对应于函数生成的指令代码在内存中的地址,因此函数名可以直接赋给指向函数的指针
  • 调用函数实际上等同于"调转指令+参数传递处理+回归位置入栈",本质上最核心的操作是将函数生成的目标代码的首地址赋给CPU 的PC 寄存器
  • 因为函数调用的本质是跳转到某一个地址单元的code 去执行,所以可以"调用"一个根本就不存在的函数实体
typedef void (*lpFunction) ( ); < 定义一个无参数、无返回类型的函数指针类型
< 定义一个函数指针,指向CPU 启动后所执行第一条指令的位置
lpFunction lpReset = (lpFunction)0xF000FFF0;
lpReset();   < 函数调用

《微型计算机原理》中讲到,186 CPU 启动后跳转至绝对地址0xFFFF0,该地址对应到C语言中为上述例子中的0xF000FFF0,其中0xF000为段地址,0xFFF0为段内偏移。
在上述例子中,根本没有定义函数,但是却能够执行lpReset()函数的调用,它实际的作用为"软重启",使程序跳转到CPU启动后第一条要执行的执行位置。

动态申请内存

在嵌入式系统中动态内存申请存在比一般系统编程时更严格的要求,这是因为嵌入式系统的内存空间往往是十分有限的,不经意的内存泄露会很快导致系统的崩溃。
因此,maloc和free一般要保证成对出现。

char *Function(void) {
  char *p = NULL;
  p = (char *)malloc(sizeof(char));
  ...
  return p;
}

void main() {
  char *q = Function();
  ...
  free(q);
}

上面这个例子明显是不合理的,因为它违反了"谁申请,就由谁释放"的原则。若程序不满足这个原则的话,会导致代码的耦合度增大,使用者需要在调用的时候知道Function()函数中的具体实现。
正确做法应该如下:

void Function(char*p) {
  ...
}

void main() {
  char *q = malloc(sizeof(char));
  ...
  Function(q);
  ...
  free(q);
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式基地

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值