找回密码
 立即注册
查看: 1274|回复: 6

C/汇编理论探究 ·【指针的基本概念】

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:58
  • 最近打卡:2025-05-31 11:37:09

12

主题

28

回帖

255

积分

中级会员

积分
255
发表于 2023-11-12 00:00:30 来自手机 | 显示全部楼层 |阅读模式
ORG 0030H ;「整活😋」(跳过中断入口地址)
现在的C语言如此强大,最离不开的就是指针。
可以说任何语言都离不开指针,学习一种语言最深的领悟就是学会其指针的作用和工作原理。

小辈无聊期间,搜寻了一下网上用汇编语言来形容C语言的例程,发现绝大多数不是用机器编译就是直接写底层寄存器之间的调用。看完后觉得不够直观,不能让大伙更直观的理解到C语言中的指针在汇编语言中类似于什么样的形式,所以本人自顾自的想要以浅薄的学识,用111条助记符的方式来解释一下指针的概念和原理。如有错误,还请各位长辈指出,莫要让新人学习了错误,误了事。

如已经基本了解C语言指针 请跳转至分界线

*/& 是C语言中指针的定义符号。定义一个指针:int *p 可以将其想象为:*表示定义了一个小盒子🎁 &表示定义小盒子的位置(即地址)。那么用初中数学代数的概念,将*p代换过来,意思就是说p成为了一个小盒子🎁。如果这个时候有一个int类型的函数number,它的地址为0010h,值为5。想将它的地址赋值给*p,则需要用到&(取地址指针)即*p = &number;如此一来 小盒子🎁“p”的名字(数值)就与number的地址相同。即p=0010h;也就是说现在这个盒子🎁就变的跟number的地址相同了。那既然地址相同了,就代表盒子跟number的盒子一样了,那里面的值一样吗?如果想要将知道答案,我就需要用到先前说到的“ * ”指针(取数值);测试结果为*p = (number)= (0010h)= 5。
在此 C语言中指针的概念就大致如此。

即当定义*p=&number时 p的数值就等同于number的地址 如果想要知道number的值则需要将p中的值作为地址打开,将其中的数据拿出来,则为number的数据(汇编中通常将括号“ () ”看成 将其中的数值作为地址看待;格式中将“ #XX ”作为数据看作)。
即*p=(number)= (0010h)= 5;
p= number = 0010h 。
(温馨提醒如果想知道定义后的指针地址,即&p。则要根据定义类型来思考。因为指针本身也需要地址来作为指向标,所以指针都会在所在数据地址的“前”方,具体前多少 需要看定义符号,如int则是4byte,即4*8=32bit(32位)因为一个地址能存储8位数据,所以真实指针的地址 在定义指针的前4个字节的位置,即前4H个的地址。
如上所述,即&p = number-4H = (0010H-0004H)= 000CH
(数据从小往大增加 前4个地址即为当前地址位减去4个地址,“十六进制数借1当16” )

////////////////////////////////////////////////////////////
//////////////////////分界线//////////////////////////
//////////////////////////////////////////////////////////

现在大伙都已经明白了指针的基本概念,那我们来看看用汇编语言怎么描述基本的指针概念。

在基本了解指针后,发现其无非就是“取地址,取数据(取数值)”。那么我们在汇编语言111条指令中就需要用到“ @ ”符号,@符号表示将当前函数的地址打开 将里面的内容,即数据,再次作为新的地址,再从其新地址中把数据取出。
脑子烧了吧…哈哈,其实就是这意思:
【在汇编语言中@能使用的通用寄存器Ri就只有R0和R1。即地址00H,01H(低128B第0组通用寄存器R0/R1地址,可在8051微机原理中了解)】
MOV 30H,#0FFH
MOV R0,30H
MOV A,@R0
此程序就是将R0中的数据作为新地址,又因为R0本身地址为00H 则需要先打开R0地址然后再打开其中的地址
即:
((R0))= ((00H))经打开一次后
((00H))—> (30H)再打开一次后
(30H)—> 0FFH
【所以可以理解成“ MOV A,@R0 ”这条指令就是把数据#0FFH 传送给了累加器A(高128B特殊寄存器 地址0E0H;;;需要注意的是汇编语言中“ # ”符号仅在程序中才作为数据,在注释描述中只是为了方便读者理解其为数字 而非地址 才使用的】

以上就是汇编助记符指令描述C语言指令的基本概念啦~^_^😋 当然这只是作为指令操作概念来理解的。
【如果想要理解 汇编指令指针在单片机的RAM中是怎么动作的需要引入真正意义上的指针 即“ SP ”堆栈指针 和 “ DPTR ”数据指针。但单片机操作最多的指针就是SP,这个东西很复杂 主要就是完完全全的描述 各条指令是怎么工作的 比如中断触发后 子程序调用后 单片机是怎么工作的。有些许复杂,我还没捋好思路怎么讲出来,如果各位前辈或汇编爱好者想了解的,可以留言,我会抽时间整理一下。】
以上就是我所想让大家理解汇编语言指针的操作概念,希望大家喜欢👀😋
END ;(程序结束)
C语言指针概念描述 参考B站 BV1Gi4y1w7yG。
IMG_6730.png
IMG_6764.png
IMG_6763.png
LED点亮世界🇨🇳
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:58
  • 最近打卡:2025-05-31 11:37:09

12

主题

28

回帖

255

积分

中级会员

积分
255
发表于 2023-11-13 00:48:05 来自手机 | 显示全部楼层
8051部分特殊寄存器地址
8051位寻址地址
IMG_6739.jpeg
IMG_6740.jpeg
LED点亮世界🇨🇳
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:535
  • 最近打卡:2025-06-18 00:09:08

1

主题

120

回帖

1917

积分

金牌会员

积分
1917
发表于 2023-11-16 00:17:03 | 显示全部楼层
学习了
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:501
  • 最近打卡:2025-06-19 08:18:37
已绑定手机

14

主题

1312

回帖

3360

积分

论坛元老

积分
3360
发表于 2024-1-26 10:45:34 | 显示全部楼层
指针就是变量的地址,不同类型的变量对应地址的“”宽度“”不一样。
先学汇编在学C理解起来很简单,单纯学C就是不容易理解。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:401
  • 最近打卡:2025-06-19 11:34:56

12

主题

126

回帖

1803

积分

金牌会员

积分
1803
发表于 2024-3-3 12:50:39 来自手机 | 显示全部楼层
我认为的指针实际就是一个内存地址,定义时用*P代替而己,而且是定义变量时指向变量在内存的首地址,然后可以用+1调用后面的地址,如果调用不当可以超出变量范围而调用错误数据,循环取数据的过程中指针地址也会变化的,所以指针就是方便取内存数据而设计的直接指向内存地址的命令,
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:13
  • 最近打卡:2025-05-28 09:08:49

34

主题

1094

回帖

2454

积分

荣誉版主

积分
2454
发表于 2024-3-3 17:13:35 | 显示全部楼层
本帖最后由 tzz1983 于 2024-3-3 17:20 编辑

简单点来理解, C语言的指针包含两个信息:
1. 地址
2. 这个地址存放了什么类型的数据

指针类型  实际上是指针指向的地址存放的数据的类型, 比如字符型指针,  整形指针.

指针自身的宽度  和硬件相关, 比如 51内核的IDATA最多256字节, 8位足够表示所有地址  (idata *)指针自身的宽度是8位.   

不同类型指针之间的强制转换规则  地址不变, 指向的数据类型改变.   比如  int a=0x3355;  int * pt=&a;  char b = *((char *)pt);  //结果是 b=0x33;  地址不变, 因为C51是高字节存在前面, 只读1字节char 即读到的数据是0x33

指针是一个二进制的地址, 所以任何指针都可以转换为整形数据, 前提是整形的宽度容得下指针.  反过来 整形亦可转换为指针, 比如  int *pv = 0x3366;

有两种特殊的指针:
1.  void* 指针, 这种指针只包含地址, 没有说明这个地址上放的是什么类型的数据,  所以用这个指针前要先转换为有类型的指针再使用,  接上例  void * p = &a;    如果直接 int c =*p; 编译器报错, 编译器表示我不知道地址P内存的是什么数据. 正确的语句是 int c = *((int*)p);
2. 函数指针.  函数经编译器编译过后就是一段汇编代码, 代码需要存在ROM内, 所以函数也是有地址的.  函数指针就是指向函数的指针,  函数除了有地址外, 还有形参格式, 所以函数指针也包含这类信息. 比如定义函数指针时, 需要用这样的书写格式:
int (*f) (int x); /* 声明一个函数指针 */  即声明指针的同时,也要声明形参格式.

回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:501
  • 最近打卡:2025-06-19 08:18:37
已绑定手机

14

主题

1312

回帖

3360

积分

论坛元老

积分
3360
发表于 2024-3-3 20:29:03 | 显示全部楼层
要想好好从原理上学习、体验指针,可以用C写功能,编译为汇编来理解。
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-19 13:20 , Processed in 0.134844 second(s), 91 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表