可能有人会觉得这个问题太简单了,几乎所有国内能找到的资料中都有介绍,pdata
是指外部扩展内存的低256字节。
我曾经很长一段时间也是这么认为的,但这……真的就是对的吗?
让我们重新回顾一下data
、idata
、xdata
和pdata
的区别:
data
是内部RAM的低128字节,即可以使用直接寻址也可以使用间接寻址。
从汇编层面来看的话,假设想把0x12这个数存到data区域中0x11这个地址中,下面的写法都是可以的:
mov 11H, #12H
mov R0, #11H
mov @R0, #12H
idata
是内部RAM的高128字节,只能使用间接寻址。 从汇编层面来看的话,假设想把0xA0这个数存到idata
区域中0x81这个地址中,只能使用下面的写法:
mov R0, #81H
mov @R0, #A1H
xdata
是外部扩展内存,最大寻址范围是64K字节,只能使用间接寻址,并且地址寄存器使用的是比较特殊的DPTR
,之所以说它特殊是因为DPTR
是一个16位寄存器(可分为DPH和DPL两个8位寄存器)。
从汇编层面来看的话,假设想把0x34这个数存到xdata
区域中0x1234这个地址中,只能使用下面的写法:
mov A, #34H
mov DPTR, #1234H
movx @DPTR, A
pdata也是外部扩展内存,只能使用间接寻址,但它使用R0
或R1
作为地址寄存器,由于R0
和R1
都是8位寄存器,所以pdata
的寻址范围是256字节。
从汇编层面来看的话,假设想把0x56这个数存到pdata
区域中0x34这个地址中,只能使用下面的写法:
mov A, #56H
mov R0, #34H
movx @R0, A
到这里为止一切似乎都是完美的,由于pdata
使用了R0
或R1
作为地址寄存器,所以它的寻址范围最大只能到255,这不就是外部扩展内存的低256字节吗?
我另一篇帖子中注意到了了sdcc的xdata初始值不正确问题(见https://www.stcaimcu.com/thread-18141-1-1.html),后来现在sdcc源码中看到,在处理xdata内存时,也只使用了8位地址寄存器R0
和R1
,不过另外配合了另一个地址高8位寄存器_PAGE
(其实就是P2
)。

结合这张图就很明了了,传统8051扩展RAM时,用到了P0
和P2
端口,P0
是8位低地址和8位数据复用,P2
是8位高地址。当使用R0
和R1
作为地址寄存器时,虽然看起来只能访问256字节的扩展内存,但只要配合好用P2锁存高8位的地址,仍然可以完整访问整个扩展RAM的64KB地址空间。
最后回到开头的问题,pdata是外部扩展内存的低256字节吗?
答:不是!还需要看当前的分页(page),这其实也是pdata中p的由来。
再附注:由于STC单片机是内部模拟的扩展RAM,整个page机制是完全失效的,所以再使用pdata
很可能产生bug,这应该也是STC官方强烈建议不要使用pdata
的原因。