注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

信息 灵感 创新

III = Information,Inspiration,Innovation

 
 
 

日志

 
 
关于我

we are 5. Mathematics, Computation, Programming, Engineering, and Making fun of life.

网易考拉推荐

C51生成汇编代码剖析(3)  

2017-10-31 10:37:19|  分类: C51(C&ASM) |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

关于指针(1)

测试如下程序生成的汇编代码:

C51生成汇编代码剖析(3) - Lemniscate - 信息 灵感 创新

 从C代码可知这个程序申明了两个变量以及一个对应的指针,分别让指针指向这两个变量,并修改其值。

在反汇编代码中,可以看到c1的地址是0x08c2的地址是0x09,看看指针初始化,指向变量的操作:

     8:     ptr_c=&c1;

C:0x0009    7B00     MOV      R3,#0x00

C:0x000B    7A00     MOV      R2,#0x00

C:0x000D    7908     MOV      R1,#0x08

可见,使用到了R1R2R33个寄存器,其中R1中的内容就是c1的地址0x08,而R2R3中为0。但是这两个地方的含义不大一样。重点在下面:

     9:     *ptr_c=0xaa;

C:0x000F    74AA     MOV      A,#0xAA

C:0x0011    12001E   LCALL    C?CSTPTR(C:001E)

这两句是通过指针的方式为其指向的地址空间赋值,显然累加器A中存放了赋值的立即数,但是调用了一个C?CSTPTR的函数,并不是源代码中编写的,因此,肯定是在链接的时候加进去的,看看这段代码的内容(首地址在0x001E):

                 C?CSTPTR:

C:0x001E    BB0106   CJNE     R3,#0x01,C:0027

C:0x0021    8982     MOV      DPL(0x82),R1

C:0x0023    8A83     MOV      DPH(0x83),R2

C:0x0025    F0       MOVX     @DPTR,A

C:0x0026    22       RET     

C:0x0027    5002     JNC      C:002B

C:0x0029    F7       MOV      @R1,A

C:0x002A    22       RET     

C:0x002B    BBFE01   CJNE     R3,#0xFE,C:002F

C:0x002E    F3       MOVX     @R1,A

C:0x002F    22       RET     

代码有点长,但并不难理解,根据0x001E比较R3的值和0x01,采取不同的动作。

1.     (R3)=0x01。执行0x00210x0026的代码,可以看到,这段代码是操作外部存储器的(MOVX),且R2中放置的是地址的高位,R1中放置的是低位,把A中的内容写入到DPTR之后返回。

2.     如果R3中内容不是0x01,代码跳转到0x0027,又分为两种情况:

l  (R3)<0x01,则标志位C被设置为1,程序顺序执行,执行0x00290x002A的代码,这一段,本例子中的C代码就是执行这条分支,最后A中的值被写入到R1所指向的地址(0x08)

l  (R3)>0x01,则标志位C被设置为0,程序跳转0x002B。此时又比较(R3)0xFE,如果是0xFE,否则把A中的内容写入R1地址所指向的外部寄存器,如果不是0xFE,则直接返回。

因此,通过以上分析可知:

初始化指针时,指向的地址储存在R1R2中,并且R3中决定了指向的是内部存储器还是外部存储器,根据 C?CSTPTR函数中的表现可知:

(R3)=0x00:内部存储器

(R3)=0x01:外部存储器(xdata)

(R3)=0xFE:外部存储器的低256位地址(pdata)

(R3)=其他值:不做任何操作(但C标志位会受影响)。

测试:

C51生成汇编代码剖析(3) - Lemniscate - 信息 灵感 创新

可以看到,0x000E和0x0019中,R3的值分别为0xFE和0x01(分别对应pdata和xdata)。

 在使用指针赋值的时候,不管是内部存储器还是外部存储器,都调用了同一个函数。另外,似乎可以断言,如果R3为0的时候,R2一定为0(因为内部存储器地址空间只在0x00-0xff,一个放在R1中的字节就可以表示)。

  评论这张
 
阅读(23)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017