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位的指针才行。
回复
我要赚赏金打赏帖 |
|
|---|---|
| 【FreeRtos】FreeRtos + MPU模块的配置使用被打赏¥32元 | |
| 【分享开发笔记,赚取电动螺丝刀】墨水屏文本显示器被打赏¥25元 | |
| 【STEVAL-STWINKT1B】:结合STMcubeMX读取磁力计iis2mdc被打赏¥19元 | |
| 【STEVAL-STWINKT1B】:结合STMcubeMX读取LPS22HH气压、温度被打赏¥19元 | |
| 【STEVAL-STWINKT1B】:结合STMcubeMX读取STTS751温度被打赏¥17元 | |
| 【STEVAL-STWINKT1B】:结合STMcubeMX软件读取HTS221温湿度被打赏¥22元 | |
| M5PAPERESP32EINKDEVKIT评测|使用MicroPython开发M5Paper被打赏¥15元 | |
| OK1126B-S开发板下以导航按键控制云台/机械臂姿态调整被打赏¥29元 | |
| 【树莓派5】便携热成像仪被打赏¥36元 | |
| 【树莓派5】环境监测仪被打赏¥35元 | |
我要赚赏金
