《匠人手记》推荐网上购书渠道:
互动出版网(china-pub)购书入口   >>>
当当网(dangdang)购书入口   >>>
卓越亚马逊网 购书入口   >>>
淘宝网(taobao)购书入口   >>>
更多购书渠道……   >>> 

设为首页加入收藏联系匠人管理入口21IC首页21IC博客21IC社区侃单片机回复的贴参与的贴

天气预报
百宝日历
载入中...

百宝专栏

载入中...
最新货色

载入中...

粉丝评论

载入中...

载入中...



百宝信息

载入中...

百宝流量

(2006-07-01开始)


匠人手记

 匠人观点: 好记性不如烂笔头  
 黑色幽默:三鹿门——后世畅想

《指针类型和存储区的关系详解》
程序匠人 发表于 2005-9-27 10:52:00  阅读全文 | 回复(0) | 引用通告 | 编辑

 《指针类型和存储区的关系详解》 作者:心意无涯?
--- 摘自《C51BBS离线版光盘》---

指针类型和存储区的关系详解

一、存储类型与存储区关系

    data     --->    可寻址片内ram
    bdata    --->    可位寻址的片内ram
    idata    --->    可寻址片内ram,允许访问全部内部ram
    pdata    --->    分页寻址片外ram (MOVX @R0) (256 BYTE/页)
    xdata    --->    可寻址片外ram (64k 地址范围)
    code     --->    程序存储区 (64k 地址范围),对应MOVC @DPTR

二、指针类型和存储区的关系

    对变量进行声明时可以指定变量的存储类型如:
    uchar data x和data uchar x相等价都是在内ram区分配一个字节的变量。

    同样对于指针变量的声明,因涉及到指针变量本身的存储位置和指针所指向的存储区位置不同而进行相应的存储区类型关键字的
使用如:

    uchar xdata * data pstr

    是指在内ram区分配一个指针变量("*"号后的data关键字的作用),而且这个指针本身指向xdata区("*"前xdata关键字的作用),
可能初学C51时有点不好懂也不好记。没关系,我们马上就可以看到对应“*”前后不同的关键字的使用在编译时出现什么情况。

    ......
    uchar xdata tmp[10];    //在外ram区开辟10个字节的内存空间,地址是外ram的0x0000-0x0009
    ......

    第1种情况:

    uchar data * data pstr;
    pstr=tmp;

    首先要提醒大家这样的代码是有bug的, 他不能通过这种方式正确的访问到tmp空间。 为什么?我们把编译后看到下面的汇编
代码:

    MOV 0x08,#tmp(0x00)        ;0x08是指针pstr的存储地址

    看到了吗!本来访问外ram需要2 byte来寻址64k空间,但因为使用data关键字(在"*"号前的那个),所以按KeilC编译环境来说
就把他编译成指向内ram的指针变量了,这也是初学C51的朋友们不理解各个存储类型的关键字定义而造成的bug。特别是当工程中的
默认的存储区类为large时,又把tmp[10] 声明为uchar tmp[10] 时,这样的bug是很隐秘的不容易被发现。

    第2种情况:

    uchar xdata * data pstr;
    pstr = tmp;

    这种情况是没问题的,这样的使用方法是指在内ram分配一个指针变量("*"号后的data关键字的作用),而且这个指针本身指向
xdata区("*"前xdata关键字的作用)。编译后的汇编代码如下。

    MOV 0x08,#tmp(0x00)        ;0x08和0x09是在内ram区分配的pstr指针变量地址空间
    MOV 0x09,#tmp(0x00)

    这种情况应该是在这里所有介绍各种情况中效率最高的访问外ram的方法了,请大家记住他。

    第3种情况:

    uchar xdata * xdata pstr;
    pstr=tmp;

    这中情况也是对的,但效率不如第2种情况。编译后的汇编代码如下。

    MOV DPTR, #0x000A        ;0x000A,0x000B是在外ram区分配的pstr指针变量地址空间
    MOV A, #tmp(0x00)
    MOV @DPTR, A
    INC DPTR
    MOV A, #tmp(0x00)
    MOVX @DPTR, A

    这种方式一般用在内ram资源相对紧张而且对效率要求不高的项目中。

    第4种情况:

    uchar data * xdata pstr;
    pstr=tmp;

    如果详细看了第1种情况的读者发现这种写法和第1种很相似,是的,同第1 种情况一样这样也是有bug的,但是这次是把pstr分
配到了外ram区了。编译后的汇编代码如下。

    MOV DPTR, #0x000A        ;0x000A是在外ram区分配的pstr指针变量的地址空间
    MOV A, #tmp(0x00)
    MOVX @DPTR, A

    第5种情况:

    uchar * data pstr;
    pstr=tmp;

    大家注意到"*"前的关键字声明没有了,是的这样会发生什么事呢?下面这么写呢!对了用齐豫的一首老歌名来说就是 “请跟我
来”,请跟我来看看编译后的汇编代码,有人问这不是在讲C51吗? 为什么还要给我们看汇编代码。C51要想用好就要尽可能提升C51
编译后的效率,看看编译后的汇编会帮助大家尽快成为生产高效C51代码的高手的。还是看代码吧!

    MOV 0x08, #0X01            ;0x08-0x0A是在内ram区分配的pstr指针变量的地址空间
    MOV 0x09, #tmp(0x00)
    MOV 0x0A, #tmp(0x00)

    注意:这是新介绍给大家的,大家会疑问为什么在前面的几种情况的pstr指针变量都用2 byte空间而到这里就用3 byte空间了
呢?这是KeilC的一个系统内部处理,在KeilC中一个指针变量最多占用 3 byte空间,对于没有声明指针指向存储空间类型的指针,
系统编译代码时都强制加载一个字节的指针类型分辩值。具体的对应关系可以参考KeilC的help中C51 User's Guide。

    第6种情况:

    uchar * pstr;
    pstr=tmp;

    这是最直接最简单的指针变量声明,但他的效率也最低。还是那句话,大家一起说好吗!编译后的汇编代码如下。

    MOV DPTR, #0x000A        ;0x000A-0x000C是在外ram区分配的pstr指针变量地址空间
    MOV A, #0x01
    MOV @DPTR, A
    INC DPTR
    MOV DPTR, #0x000A
    MOV A, #tmp(0x00)
    MOV @DPTR, A
    INC DPTR
    MOV A, #tmp(0x00)
    MOVX @DPTR, A

    这种情况很类似第5种和第3种情况的组合,既把pstr分配在外ram空间了又增加了指针类型的分辨值。

    小结一下:大家看到了以上的6种情况,其中效率最高的是第2种情况,既可以正确访问ram区又节约了代码,效率最差的是第 6
种,但不是说大家只使用第2种方式就可以了,还要因情况而定,一般说来应用51系列的系统架构的内部ram资源都很紧张,最好大家
在定义函数内部或程序段内部的局部变量使用内ram,而尽量不要把全局变量声明为内ram区中。所以对于全局指针变量我建议使用第
3 种情况,而对于局部的指针变量使用第2种方式。

    C51是很灵活的,也很好理解和使用,但要成为笑傲江湖的一代高手还是要多想多练,没有实际项目的锻炼是不容易提高的。希
望这篇文章对大家一点用处。

    ...... 待续

    参考:

    《单片机的C语言应用程序设计》-马忠梅 等编著
    《KeilC-help-C51 User's Guide》-Keil Software

声明:此文章未经作者本人同意不等用于商业目的,OICQ:6001603,EMail:sitnc@hotmail.com [Hero] 心意无涯
 
 
Copyright? 2001-2002, 晓奇工作室 E-Mail:info*xiao-qi.com 
 

 

看《匠人手记》,与匠人同行!北航出版,正在热卖!

发表评论:
载入中...

芯片专题

器件专题

软件专题

硬件专题

综合专题

项目专题

原创专题

器件检测
LCD LED
按键 触摸键
E2PROM
电池 电机
电阻 电容 电感

指令系统
软件算法
编程规范
滤波算法
串行通讯

PCB设计
I2C PWM
红外遥控
充电技术
中断 ADC 

匠人手记
匠人夜话
网络心路
一周热点串烧
从零开始玩PIC
DIY旋转时钟

广告5号位 [投放]


学习板、开发板、编程器、下载器、仿真器(查看详情……)

广告3号位 [投放]

站内搜索


站外搜索


百度  google
mp3  歌词 
图片  FLASH 
知道  文档
新闻  词典 
地图  mp3 
软件  天网 
雅虎  爱问 
搜狗  讯雷 
网讯  华军 
天空 

21IC器件搜索
百宝箱分站
  • 《匠人的百宝箱》21IC站
  • 《匠人的百宝箱》21IC笔记团队
  • 《匠人手记》21IC书友会
  • 《匠人的百宝箱》MCUBLOG站
  • 《匠人的百宝箱》MCUBLOG笔记团队
  • 《匠人的百宝箱》EDN站
  • 《匠人手记》EDN书友会
  • 《匠人的百宝箱》与非网站
  • 《匠人的百宝箱》新浪站
  • 《匠人的百宝箱》百度站
  • 《匠人的百宝箱》网易126站
  • 《匠人的百宝箱》网易163站
  • 《匠人的百宝箱》互动出版网站
  • 广告4号位 [投放]

     
     

    匠人原创

    往日酷贴

     
     
     

    大千八卦

    友情连接

    新浪新闻:
    新浪财经:
    AK58新闻:
    新浪股票:
    新浪股票:
    证券之星:

     [更多酷站连接]

     

     

    [欢迎交换连接]

    [百宝箱之与非门分舵]

    [电脑圈圈的家当]

    [IC921的博客]

    [柔月阁]

    [八楼的呼吸]

    [hotpower 的水潭]

    [xwj的文君阁]

    [所长的BLOG]

    [阿摆手记]

    [电子伙伴]

    [unaided的笔记]

    [小飞的笔记]

    [单片机开发联盟]

    [网址之家]

    [好东西网址大全]

    [美萍中文精选]

    [数字电视之家]

    [SMARTCODE电子书斋]

    [软件开发之窗]

    [Armoric]

    [我爱研发网]

    [infernal的笔记]

    [雄鹰的空中加油站]

    [SunK]

    [逍遥电子]

    [ningpanda的博客]

    [C-Design]

    [一网见天下]

    [海边淘沙]

    [嵌入式365]

    [水牛的仓库]

    [股剩是怎样炼成的]

    [PIC论坛]

    [ICC AVR开发网]

    [中国高校自动化网]

     

     

     

    MCU博客-中国电子工程师博客网 

    大学生电子网 

     

     

     

     

     

    !!! 《匠人的百宝箱》 !!!