回复:指针难题询问

Letham

西门子1847工业学习平台

  • 帖子

    2082
  • 精华

    43
  • 被关注

    362

论坛等级:至圣

注册时间:2006-04-15

白金 白金 如何晋级?

发布于 2017-07-19 09:44:34

11楼

展开查看
以下是引用meiruhua在2017-07-19 09:17:10的发言 >10楼

意思是不是:L W[AR1,P#0.0]这个是取数据编号  L D[AR1,P#2.0]这个把后面的4个字节也就是这个数据存储的拿出来接下来比如 L B[AR1,P#0.0]这个时候才是取出数据的第一个字节的内容。

以下是引用Letham在2017-07-14 09:14:02的发言 >7楼:需要了解下 指针类型...

引用7楼详细内容:

需要了解下 指针类型POINTER 结构 就明白了!

Pointer可以理解成指向指针的指针,它所占的6个字节的地址空间分别指向一个DB块号(如果是DB,非DB内存则为0)和实际的指针地址

至于怎么取那个DB号,正常时,那个是由CPU操作系统在调用这段程序,在实参赋值形参时 自动赋值到W[AR1,P#0.0]里的 。D[AR1,P#2.0]就是指针地址了(当然 ,也可以手动给POINTER所占的地址赋值,比如FB里IN_OUT类型的 一个数据结构,由于FB在调用时可以不分配实参,所以你可以在程序内部手动赋值,这样更灵活 在程序执行期间可以指向任意地址空间和DB块)

比如

L P##P  FB里IN_OUT类型一个复杂数据类型,UDT等

OPEN DB10 

L DBNO

T W{AR1,P#0.0]




以下是引用meiruhua在2017-07-12 09:28:56的发言 >3楼: L W [ AR1 , ...

引用3楼详细内容:

 L W [ AR1 , P#0.0 ]     我就不明白这步是怎么取那个DB号的

以下是引用艾星落尘在2017-07-11 13:12:30的发言 >:      L    ...

引用详细内容:

      L     P##S1           //取指针地址,从下面的使用情况来看因该是POINTER     

      LAR1                    

      L     P##S2           //取指针地址,从下面的使用情况来看因该是POINTER       

      LAR2                       

      L W [ AR1 , P#0.0 ]        

      T     #w_Temp          //取S1对应的DB号给 #w_Temp     

      OPN DB [ #w_Temp]       //打开#w_Temp 对应的DB块   

      L D [ AR1 , P#2.0 ]          

      LAR1                    //取S1指针对应的地址数据存入AR1                 

      L W [ AR2 , P#0.0 ]        

      T     #w_Temp           //取S2对应的DB号给 #w_Temp        

      OPN DI [ #w_Temp]       //打开#w_Temp 对应的背景DB块       

      L D [ AR2 , P#2.0 ]         

      OD    16#0100_0000     //这个逻辑或的作用应该是将该地址转化为背景数据    

      LAR2                   //取S2指针对应的地址数据存入AR2        

      SET

      SAVE                      

      L B [ AR1 , P#1.0 ]     //取S1对应的DB块的数据的第二个字节,应该是字符串实际使用的数据  

      +     1                   

LOP:  T     #y_Loop              

      L B [ AR1 , P#1.0 ]        

      L B [ AR2 , P#1.0 ]   //因为是字节进行比较所以就有了 OD    16#0100_0000  这段指令     

      <>I                    //两个DB块的字符串进行比较不等就跳转到循环外,       

      JC    RESE               

      +AR1  P#1.0                

      +AR2  P#1.0           

      L     #y_Loop

      LOOP  LOP               //如果比较的结果相等就继续执行,知道循环数结束为止

      S     #EQ_STRNG         //比较结果都相等就置位#EQ_STRNG    

      JC    ENDE               

RESE: R     #EQ_STRNG         //比较结果有不等的就复位#EQ_STRNG     

ENDE: BE


L W[AR1,P#0.0] 是取DB号 这个是没问题(不是DB数据区,为0),L D[AR1,P#2.0] 是取指针地址。至于AR1类容是什么 你可以不必关心,这个是实参到形参赋值时,由操作系统赋值的,一般AR1指向L区。

比如 你的 POINTER在进行调用时实参 DB1.DBB20-DBB50 这个字符串区域。

下面打比方来进行注解

在系统调用后

你在程序里通过

L P##S1

操作系统会自动把 S1这个POINTER 类型 的 所占的空间的首地址,放到L区里(还有一个区叫V区 ,其实它就是特殊的L区,简单介绍同一叫L区吧,这个不必深究,也没有太大意思),这个L区开始的6个字节的类容就是POINTER结构是对应的。比如 经过调用后,假设系统把这个指针的类容放到LB10-LB15 6个字节里。

执行上面的语句后,一般会通过 LAR1 把 这个L区的首地址P#10.0 放到的AR1寄存器里。AR1寄存器类容是P#L10.0

下面开始分析POINTER ,

上面 已经知道AR1 里类容是P#L10.0,那么通过 L W[AR1,P#0.0]实际上就是L LW10 ,L D[AR1,P#2.0] 就是 L LD12,那么LW10 里面是什么了?当然是DB号就是1,那么LD12里是什么了,当然是指向DB1.DBB20这个地址,也就是P#20.0(DB1.DBB20)

你的程序中

  L D [ AR1 , P#2.0 ]   //AR1类容是P#L10.0

    

  LAR1     //此语句过后,AR1里面类容就变成了指向实参的DB1.DBB20-DBB50这个字符串的首地址            //P#20.0了

如果后面再加个 L D [ AR1 , P#2.0 ]语句 

这个时候 不是相当于 L LD12了,而是 L DB1.DBD22了  ,直到这一步。指针才真正指向DB1.DBB20-50的类容;                



码了这么多字 懂了不?理解POINTER 关键是 理解 POINTER是个指向指针的指针。

人生就像一场旅行!
评论
编辑推荐: 关闭

请填写推广理由:

本版热门话题

SIMATIC S7-300/400

共有54767条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

快扫描右侧二维码晒一晒吧!

再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!

  • 分享

  • 只看
    楼主

top
X 图片
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。