51编译器把所有的指针都统一成3字节,大概是为了统一计算。但是51里所有的寻址确实最多只要16字节就搞定了,我猜多出来的那个字节可能是最初设计C51的人预留出来的吧。。。。
正常51的寻址是:
data,idata,pdata 关键字修饰的变量地址是8位即一个字节。
xdata,code 关键字修饰的变量地址是16位即两个字节。
但是无论用什么关键字修饰指针,其都占用3个字节大小。对任何取值行为得到的sizeof的值也是3。
在keil4调试的时候,可以观察到所有的xdata类型的地址长度确实是3字节,但是高字节总是0。我尝试在工程设置中将外部RAM的起始地址设置成0xFFFF以后,结果想当然的失败了(51的外部RAM、ROM扩展只有16条地址线)。我也有想过指针的最高字节可能储存了变量的类型,但是实验结果表明无论是char 、int、还是unsigned int,最高字节还是0。这真是一个神奇的第3字节。看看有谁能挖到为什么。
这也告诉我们用C51编程使用指针是比较浪费内存的。
又做了实验,指针的最高字节确实代表了类型,不过是代表了地址类型。
最高字节 | 地址类型 |
0x00 | data、idata |
0x01 | xdata |
0xfe | pdata |
0xff |
code |
因此,由于最大16位的寻址能力加上51乱七八糟的寻址方式,其指针需要3字节空间。
比如将指针作为参数传递到子函数中时,如果无法判断地址类型,将无法获得正确的值。
没有用过AVR,PIC也不熟,不知道这两个系列的8位机是怎么样的。
比较熟悉的ARMcortex核心的STM32,因为其只有一个地址空间,FLASH、RAM、extRam、寄存器等等地址都在一个向量空间中,不存在地址的重叠,因此其指针无需额外的一个字节来标示地址类型,就是32位4字节的。
恩,解释的非常好,谢谢。
就是说,根据存储位置的不同,定义不同长度的指针,
存储类型与存储区关系
data ---> 可寻址片内ram(0-127)
bdata ---> 可位寻址的片内ram
idata ---> 可寻址片内ram,允许访问全部内部ram(0-255)
pdata ---> 分页寻址片外ram (MOVX @R0) (256 BYTE/页)
xdata ---> 可寻址片外ram (64k 地址范围FFFFH)
code ---> 程序存储区 (64k 地址范围)
可以看出,对于data/idata来说,8位的指针就可以了,但是xdata/code需要16位的指针才行。
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 | |
【分享评测,赢取加热台】使用8051单片机驱动WS2812被打赏40分 | |
【换取逻辑分析仪】rtthread添加RRH62000传感器驱动-基于野火启明6M5被打赏48分 | |
换逻辑分析仪+Verilog多输入门被打赏27分 |