单片机c语言指针作用,单片机C语言指针意义浅析—Keil-C51

2023-10-27

通常认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用上,甚至认为指针是C语言的灵魂。这里说通常,是广义上的,因为随着编程语言的发展,指针也饱受争议,并不是所有人都承认指针的“强大”和“优点”。在单片机领域,指针同样有着应用,本章节针对Keil C-51环境下的指针意义做简要分析。

1 指针与变量

指针是一个变量,它与其他变量一样,都是RAM中的一个区域,且都可以被赋值,如程序①所示。

#include "REG52.H"

unsigned int j;

unsigned char *p;

void main()

{

while(1)

{

j=0xabcd;

p=0xaa;

}

}

在Debug Session模式下,将鼠标指针移到到变量“j”“p”位置,可以显示变量的物理地址,如图1-1、1-2所示。

6.eewimg.cn-news-uploadfile-2020-0219-1582081039628112.jpg

6.eewimg.cn-news-uploadfile-2020-0219-1582081040486972.jpg

图中箭头所指处即为变量在RAM中的“首地址”,为什么是“首地址”呢?变量根据类型可分为8位(单字节)、16位(双字节),程序中变量“j”是无符号整型,所占物理空间应为2字节,而在8位单片机中,RAM的一个存储单元大小是8位,即1字节,因此需2个存储单元才满足变量“j”长度。所以实际上变量“j”的物理地址为“08H”“09H”。同理,“p(D:0x0A)”即变量“p”的首地址为“0AH”。

下面通过单步执行程序来观察RAM内的数据变化,打开两个Memory Windows窗口,在Keil软件下方显示为Memory1和Memory2,在两个窗口中,分别做如图2-1、2-2所示的设置。

6.eewimg.cn-news-uploadfile-2020-0219-1582081040591366.jpg

6.eewimg.cn-news-uploadfile-2020-0219-1582081041533217.jpg

两个Address填写的内容分别是:D:0x08、D:0x0A,即变量“j”和变量“p”的首地址,输入后回车,便可监视RAM中该地址下的数据。设置好后,准备调试。

在Debug Session模式中,箭头所指处即为即将执行的语句,单击“Step”功能按钮(或按F11键),让程序运行,如图3所示。

6.eewimg.cn-news-uploadfile-2020-0219-1582081041424915.jpg

第一次单击“Step”按钮后,Memory1窗口内数据如图4所示。

6.eewimg.cn-news-uploadfile-2020-0219-1582081042103870.jpg

由调试结果可知,08H数据由00H变为ABH,09H数据由00H变为CDH,出现这种变化是因为执行了语句j=0xabcd;08H为变量“j”高八位,存储“AB”,09H为变量“j”低八位,存储“CD”。

第二次单击“Step”按钮,执行语句:p=0xaa;此时需观察Memory2窗口内数据,如图5所示。

6.eewimg.cn-news-uploadfile-2020-0219-1582081043232090.jpg

由调试结果可知,0CH处值由00变为“AAH”,程序相吻合。这里需要注意,在Keil C-51编译环境下,指针变量,不管长度是单字节或是双字节,指针变量所占字节数为3字节。故此处“AAH”不是存储在0AH而存储在0CH(0A+2)地址中。

综上所述,指针实际上是变量,都是映射到RAM中的一段存储空间,区别是,指针占用3字节,而其他变量可根据需要设定其所占RAM是1字节(char)、2字节(int)、4字节(long)。

2 指针作用

指针的作用是什么呢?先来看下面的程序:

程序②

#include "REG52.H"

unsigned chartab1[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};

unsigned char codetab2[8]={0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80};

unsigned char N1,N2;

void main()

{

N1=tab1[0];

N2=tab2[0];

}

显然,程序执行的结果是N1=0x01,N2=0x10。这里都是讲数组内的数据赋值给变量,但存在区别,tab1数组使用的是单片机RAM空间,而tab2数组使用的是单片机程序存储区(ROM)空间。尽管使用C语言为变量赋值时语句相同,但编译结果并不相同,此程序编译后的结果如图6所示。

6.eewimg.cn-news-uploadfile-2020-0219-1582081043821499.jpg 

由编译结果可知,N1=tab1[0]语句实际上是直接寻址,而N2=tab2[0]是寄存器变址寻址。不管是何种寻址方式,都是将一个物理地址内的数据取出来使用:tab1数组中,tab[0]对应的RAM地址是0x0A,tab[1]对应的RAM地址是0x0B……以此类推;tab2数组中,tab[0]对应的ROM地址是0x00A5,tab[1]对应的ROM地址是0x00A6……以此类推。不管这些数组或变量所在的RAM或ROM地址如何,用户最终需要的是数组或变量的数据,而指针,就是通过变量或数组的物理地址访问数据,也就是说,通过指针,同样可以访问数组或变量数据。现将程序②做出调整,得到程序③如下:

#include "REG52.H"

unsigned chartab1[8]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};

unsigned char code tab2[8]={0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80};

unsigned char N1,N2;

unsigned char  *p;

void main()

{

unsignedchar i;

p=tab1;

for(i=0;i<8;i++,p++)

N1=*p;

p=tab2;

for(i=0;i<8;i++,p++)

N2=*p;

}

程序执行结果:tab1数组内的8个数值依次被赋值给N1;tab2数组内的8个数值依次被赋值给N2;

程序③执行Debug Session功能后,打Watch Windows窗口,在Watch1窗口下添加需要监视的变量,此处为“p”和“N1”,如图7所示。

6.eewimg.cn-news-uploadfile-2020-0219-1582081044517030.jpg

Value为当前变量数值,程序为运行前,p值为0x00,单击Step按键功能后,执行p=tab1;p值变为0x0A,如图8所示。

6.eewimg.cn-news-uploadfile-2020-0219-1582081044913827.jpg

0x0A是什么值呢?将鼠标移至tab1数组位置,可显示出数组所在的物理地址,0x0A就是数组tab1的首地址,如图9所示。

6.eewimg.cn-news-uploadfile-2020-0219-1582081045964600.jpg

p=tab1就是将tab1数组的首地址赋值给变量p,执行p++即地址值加1;*p则是此物理地址内的具体数据,因此for循环中,N1=*p是依次将tab1数组中的数据赋值给变量N1。由此可见,指针是作为一个变量,指向某一个地址。

那么指针到底是如何将某个地址内的数据“拿”出来的?下面通过N1=*p语句做演示说明,N1=*p编译后的汇编代码如图10所示。

6.eewimg.cn-news-uploadfile-2020-0219-1582081045202888.jpg

C:0x00A0至C:0x00A9的汇编代码即是C程序中的N1=*p。程序先将变量p的值赋值给R3、R2、R1三个通用寄存器,程序为:

MOV   R3,p(0x12)

MOV   R2,0x13

MOV   R1,0x14

然后调用了一个子函数:LCALL  C?CLDPTR(C:00E4),而C程序中,未定义或使用任何子函数,那么这个子函数是哪里来的?作用是什么?根据标号C:00E4可找到该子函数,程序代码如下:

C:0x00E4   BB0106   CJNE     R3,#0x01,C:00ED

C:0x00E7   8982     MOV      DPL(0x82),R1

C:0x00E9   8A83     MOV      DPH(0x83),R2

C:0x00EB   E0       MOVX     A,@DPTR

C:0x00EC   22       RET

C:0x00ED   5002     JNC      C:00F1

C:0x00EF   E7       MOV      A,@R1

C:0x00F0   22       RET

C:0x00F1   BBFE02   CJNE     R3,#0xFE,C:00F6

C:0x00F4   E3       MOVX     A,@R1

C:0x00F5   22       RET

C:0x00F6    8982    MOV      DPL(0x82),R1

C:0x00F8   8A83     MOV      DPH(0x83),R2

C:0x00FA   E4       CLR      A

C:0x00FB   93       MOVC     A,@A+DPTR

C:0x00FC   22       RET

此程序功能是:先用R3寄存器的值与0x01比较,当R3的值大于0x01时,再和0xFE做比较,比较的结果有如下情况:

(1)R3的值等于0x01时,执行如下程序:

C:0x00E7   8982     MOV      DPL(0x82),R1

C:0x00E9   8A83     MOV      DPH(0x83),R2

C:0x00EB   E0       MOVX     A,@DPTR

C:0x00EC   22       RET

程序功能:读取扩展RAM内的数据并赋值给A,寻址范围0~65535。当数组用xdata定义时,会跳转到此处。

(2)R3的值小于0x01即等于0x00时,执行如下程序:

C:0x00EF   E7       MOV      A,@R1

C:0x00F0   22       RET

程序功能:读取单片机内部256字节RAM内的数据并赋值给A,寻址范围0~255。当数组用data或idata定义时,会跳转到此处。如执行N1=*p语句时,即跳转到自处,读取内部RAM地址内的数据。

(3)R3的值不等于0x00或0x01时,通过JNC指令跳转到C:0x00F1处,开始与0xFE做比较。R3的值等于0xFE时,执行如下程序:

C:0x00F4   E3       MOVX     A,@R1

C:0x00F5   22       RET

程序功能:读取单片机片外RAM内的数据并赋值给A,寻址范围0~255。当数组用pdata定义时,会跳转到此处。通常8051单片机不使用pdata定义变量或数组。

(4)R3的值不等于0xFE时,即R3的值等于0xFF时,跳转到C:0x00F6处执行如下程序:

C:0x00F6   8982     MOV      DPL(0x82),R1

C:0x00F8   8A83     MOV      DPH(0x83),R2

C:0x00FA   E4       CLR      A

C:0x00FB   93       MOVC     A,@A+DPTR

C:0x00FC   22       RET

关键字:单片机  C语言  指针  Keil-C51

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单片机c语言指针作用,单片机C语言指针意义浅析—Keil-C51 的相关文章

  • 分类算法原理及python实现(一)

    文章目录 一 分类算法的概念 1 概念 2 应用 3 统计学分类与机器学习分类的区别 4 概率模型与非概率模型基本思想 二 分类算法 1 逻辑回归 2 朴素贝叶斯 3 K近邻 一 分类算法的概念 1 概念 输出变量Y为有限个离散值的预测问题
  • WSL2中设置DNS后重启终端又失效的解决方法

    转载地址 https www xieshasha love wsldns iiMemory WSL2 用着是挺好的 就是发现了一个问题 郁闷了好久 修改 etc resolv conf可以自己设置 dns 但重启 WSL 以后 手动设置的
  • Linux系统与管理 - (四)VIM编辑器

    目录 自说 学习路径 工作模式 基本操作 自说 vim在以前unix系统中叫做VI编辑器 不过现在我们用到vim编辑器较多 它们之间最大的区别在于 vim编辑器具备有编程的能力 并且文字有各种颜色方便我们辨别 设计 vim其实类似于我们Wi
  • [附源码]计算机毕业设计Python+uniapp基于小程序的得物的租借平台se5eb(程序+lw+远程部署)

    附源码 计算机毕业设计Python uniapp基于小程序的得物的租借平台se5eb 程序 lw 远程部署 该项目含有源码 文档 程序 数据库 配套开发软件 软件安装教程 项目运行环境配置 Python3 7 7 Django Mysql5
  • FPGA学习—数码管显示

    FPGA学习 数码管显示 文章目录 FPGA学习 数码管显示 结构框架 一 硬件设计 二 verilog编写 1 计数器 2 译码模块 3 数码管扫描模块 4 顶层模块 实验结果 结构框架 数码管动态显示采用了人眼暂存的原理 即时分复用 在
  • MYSQL基础篇(一)

    前言 作者主页 雪碧有白泡泡 个人网站 雪碧的个人网站 推荐专栏 java一站式服务 React从入门到精通 前端炫酷代码分享 从0到英雄 vue成神之路 uniapp 从构建到提升 从0到英雄 vue成神之路 解决算法 一个专栏就够了 架
  • elctron项目_Electron-vue脚手架改造vue项目的方法

    1 什么是Electron Electron可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造桌面应用 你可以把它看作是专注于桌面应用而不是 web 服务器的 io js 的一个变体 这不意味着 Electron 是某个
  • pyqt5 无边框窗口拖动

    from PyQt5 QtWidgets import from PyQt5 QtCore import from PyQt5 QtGui import import sys class Example QWidget startPos N
  • ChatGPT 与 MindShow 一分钟搞定一个PPT

    前言 PPT制作是商务 教育和各种场合演讲的重要组成部分 然而 很多人会花费大量时间和精力在内容生成和视觉设计方面 为了解决这个问题 我们可以利用两个强大的工具 ChatGPT和MindShow 来提高制作PPT的效率 一 ChatGPT
  • 90+深度学习开源数据集整理|包括目标检测、工业缺陷、图像分割等多个方向

    导读 本文整理汇总了90 深度学习各方向的开源数据集 包含了小目标检测 目标检测 工业缺陷检测 人脸识别 姿态估计 图像分割 图像识别等方向 小目标检测 1 AI TOD航空图像数据集 数据集下载地址 http m6z cn 5MjlYk
  • 图解RocketMQ(一)

    目录 1 消息模型 Message Model 2 消息生产者 Producer 3 消息消费者 Consumer 4 主题 Topic 5 代理服务器 Broker Server 6 名字服务 Name Server 7 拉取式消费 Pu
  • Gitlab CI/CD

    Gitlab CI CD 1 概述 Gitlab是常用的开源git代码管理工具之一 随着发展也推出了ci cd解决方案 顾名思义具体来说ci cd主要完成以下两个工作 ci 持续构建 代码提交后触发自动化的单元测试 代码预编译 构建镜像 上
  • ubuntu 16.04+ros kinetic + gazebo+ aws-robotics 室内环境导航仿真

    背景 aws robotic ros gazebo 仿真在ros2以及ros melodic 中的使用网上讲解较多 本文主要介绍ros kinetic gazebo9 下turtlebot3 机器人在 aws robomaker small
  • C/C++课程设计学生通讯录信息管理系统,成绩管理系统,抽象封装继承多态,增删改查

    目录 一 系统设计内容及要求 需求分析 二 系统总体设计 首先构造基本框架 基本思路 三 详细设计 基本步骤 一 系统设计内容及要求 需求分析 制作一个系统实现对学生通讯信息的管理功能 可以对学生通讯信息进行录入 显示 添加 删除 修改等功
  • LU分解+求逆矩阵

    LU分解 求逆矩阵 编写了LU分解的MATLAB代码 求逆矩阵 实现了附加单位阵法和解方程法两种求逆矩阵的方法 时间 20210925 文件说明 输入矩阵A应为方阵 文件末尾进行了验证 将本文件所写算法与MATLAB的lu函数及求逆矩阵函数
  • Python之第八章 读写文件

    一 文件与文件路径 V 这是一个V 这是反斜杠 这是斜杠 Windows根目录 C linux和OS X 路径 1 windows上的反斜杠以及OS X 和 Linux上的正斜杠 os path join 方法 返回文件路径 但是我们可以用
  • Explanation on K&R 8.7 A Storage Allocator

    Anyone has a basic knowledge of C can use malloc but under the cover what really happens Well K R give us a simple versi

随机推荐

  • 实际开发中,TCP / IP 七层网络模型是如何工作的?

    目录 前言 一 五层网络模型分别是什么 通俗理解 1 1应用层 1 2传输层 1 3网络层 1 4数据链路层 1 5物理层 二 如何工作 首先是封装过程 2 1 应用层形成协议报文 2 2 传输层添加TCP报头 2 3 网络层添加IP报头
  • R绘图的图形布局,画布布置函数

    对后续的绘图参数进行修改和定义 par no readonly TRUE 1 在一张画布上进行多张图谱的绘制 par mfrow c 2 2 2 layout layout matrix c 1 1 2 3 2 2 byrow T 其中1
  • 线性代数学习笔记(十五)——初等变换(一)

    本篇笔记首先讨论了矩阵的初等变换 包括初等行变换和初等列变换两类 每一类初等变换又有三种变换规则 需要注意该初等变换与行列式对应的性质没有任何关系 然后讨论了初等变换和标准形的关系 任意矩阵都可以通过 行和列 初等变换化为标准形 最后还讨论
  • RedHat 6.9/7.4 IB网驱动安装教程

    RedHat 6 9 7 4 IB网驱动安装教程 为什么要写这次安装小结 之前安装redhat6 9已成功配置 这次需要安装7 4的驱动 二话不说跑去官网下载相应的驱动 进行安装 虽然驱动能够安装成功但是opensmd和openibd服务一
  • RobotFramework 之 文件上传和下载

    RobotFramework 之 文件上传和下载 文件上传 文件下载 在项目过程中 经常会遇到文件的上传和下载类型的操作 网上也可以找到各种方式 这里介绍的是RobotFramework框架在UI自动化过程中的文件上传和下载 文件上传 Ro
  • html中写随机数,JavaScript中的随机数,HTML随机数实现方法

    有时在网页设计过程中 需要用到随机数 对于PHP ASP Net等编程方法 要实现调用随机数 那相对很简单 但是 如果是静态HTML页面实现随机数调用 那么就只能使用JS的方法 即用JavaScript的编程设计了 在JavaScript中
  • 如何删除GitHub仓库里的文件夹(区分 rm/git rm)

    删除GitHub仓库里的一个文件夹 1 复制仓库地址 2 在本地新建一个空文件夹 3 在空文件夹内 右键选择Git Bash Here 4 弹出GIT Bash框 5 克隆远程仓库 6 拉取远程仓库 7 查看仓库里的文件 8 选择想要删除的
  • Destination Host Unreachable

    背景 物理机的IP地址是192 168 31 189 虚拟机的IP地址是192 168 194 130 物理机ping得通虚拟机 虚拟机ping得通外网 可是虚拟机ping不通物理机 1 报错信息 Destination Host Unre
  • 多线程相关知识总结

    1 并发编程三要素 1 原子性 原子性指的是一个或者多个操作 要么全部执行 要么全不执行 2 可见性 可见性指多个线程操作一个共享变量时 其中一个线程对变量进行修改时 其他线程变量可以立即看到修改的结果 3 有序性 即程序的执行顺序按照代码
  • 宏定义的正确写法,三目运算的宏定义

    转自 宏定义的正确写法 三目运算的宏定义 https my oschina net iOScoderZhao blog 916074 第一阶段 对象宏 define M PI 3 141592653589793238462643383279
  • 对症下药,方能药到病除——如何修复drv?

    前面两周介绍了如何修复setup和hold violation 这次我们接着来讲下另外一个十分重要的violation drv的修复 首先 我们来了解下drv的基本概念 drv全称design rule violation 设计规则违反 主
  • Tensorflow模型持久化 (ckpt & pb)

    文章目录 1 基本处理代码 2 模型保存为ckpt文件 3 基于ckpt文件的测试 4 模型保存为pb文件 4 1 直接保存为pb文件 4 1 1 tf graph util convert variables to constants 4
  • 24黑马QT笔记之画背景图

    24黑马QT笔记之画背景图 1 区别不是窗口的显示图片 在窗口中绘图必须重写绘图事件 在绘图事件中绘图 即用到QPainter画家和xxx begin this 函数指定绘图设备 与之前学的区别 下面的代码是在标签中显示图片 只是简单的显示
  • javascript: iframe switchSysBar 左欄打開關閉,兼容各瀏覽器操作

  • linux怎么进入字符命令界面,如何进入CentOS字符界面及窗口模式

    在CentOS界面切换问题中 也许很多人习惯进入字符工作方式来进行操作 那么如何切换到字符工作方式呢 下面我们就来介绍3种方法来进入字符工作方式 在图形环境下开启终端窗口进入字符工作方式 在系统启动后直接进入字符工作方式 使用远程登录方式
  • EMC 测试项

    一 什么是EMC EMI和EMS 1 什么是EMC 电磁兼容性 电磁兼容性 Electromagnetic Compatibility 缩写EMC是一个设备或装置与其它装置同时操作时 不会因为电磁干扰问题而影响正常工作之能力 EMC 电磁兼
  • axios给后端传数据实例

    后端部分 首先 后端controller层如下所示 此处 RequseParam内的内容即为接受的参数 附上postman请求的结果 注意key一定要和后端定义的类型一致 前端部分 即后端填写好正确的url后 只需在params里定义好要传
  • Docker中安装使用Nginx并安装SSL证书

    一 安装部署Nginx 1 在DockerHub中搜索Nginx的镜像 docker search nginx 如果不是root用户 请自行在所有命令前面加上sodu 2 拉取最新版本的官方nginx镜像 如果不写TAG号 会自动追加 la
  • 计算机网络面试题 43问汇总,面试必问

    最近整理的10w字Java面试手册 涵盖了Java面试几乎都会问的面试题目 小熊学Java在线地址 https javaxiaobear gitee io 1 OSI 七层网络模型 你了解吗 具体功能有哪些 网络的七层架构从下到上主要包括物
  • 单片机c语言指针作用,单片机C语言指针意义浅析—Keil-C51

    通常认为 C语言之所以强大 以及其自由性 很大部分体现在其灵活的指针运用上 甚至认为指针是C语言的灵魂 这里说通常 是广义上的 因为随着编程语言的发展 指针也饱受争议 并不是所有人都承认指针的 强大 和 优点 在单片机领域 指针同样有着应用