间接寻址是指用指针来访问存储区的数据。指针以双字的形式存储其它存储区的地址,只能将V存储单元、L存储单元或累加寄存器(AC1、AC2、AC3)用作指针。
创建指针时,必须使用“移动双字”指令,将间接寻址的存储单元地址移至指针位置。;用“&”符号加上要访问的存储区地址可建立一个指针,当指令中的操作数是指针时,应该在操作数前加上“*”号。
1.建立指针
建立指针记得加“&”;将VB100的地址存放到VD1000内。
2.指针偏移按字节寻址,就+1;
按字寻址,就+2;
按双字或浮点数寻址,就+4;
3.取指针 4.程序监控 1)按下M0.0,执行字节偏移,此时在VB101输入“10”,VB3000的数据即为“10”,然后复位M0.0。2)按下M0.1,执行字偏移,此时在VW102输入“50”,VW4000的数据即为“50”,然后复位M0.1。3)按下M0.2,执行双字偏移,此时在VD104输入“80”,VD5000的数据即为“80”,然后复位M0.2。程序实例(干货)
实例1:通过指针间接寻址改变定时器的3种不同定时时间。
实例2:通过指针间接寻址找一组数据的最值(大和小)和平均值。主程序
子程序
程序的监控图就不贴出来了,其实重点就在子程序的第二段,每循环一次,就做一次比较,如果比较条件满足,就将大值和小值暂存到LD10和LD14中,直到循环到最后一次,此时最大值和最小值已经找出来了,平均值就是将每循环一次的值进行累加,然后再除以数据个数,这里我就不展开仔细的分析了,可以参考一下最后一个案例,冒泡排序执行原理。
实例3:通过指针间接寻址改变5个计数器的计数值。案例4,冒泡排序,从小排到大。
主程序,排8组数据。
子程序
冒泡排序算法解析:
八组数据:分别是20.0;365.0;7.0;7.0;210.5;7.6;15.6;22.8。
1.首先将要排列的数据个数-2(8-2),然后存放到LW10中;再将这个值附给外循环的FINAL。
2.第一个外循环的执行的次数即为0~6(7次)。
3.INDX:假定 INIT 值为 0,FINAL 值为 6,则 FOR 指令和 NEXT 指令之间的指令将执行 7 次,INDX 值递增:0,1, 2, 3, 4.5.6。
第一次外循环(执行7次内循环)
第一次内循环
20.0;365.0;7.0;7.0;210.5;7.6;15.6;22.8;(20.0<365.0,位置不变)
第二次内循环
20.0;7.0;365.0;7.0;210.5;7.6;15.6;22.8;(7.0<365.0,位置改变)
第三次内循环
20.0;7.0;7.0;365.0;210.5;7.6;15.6;22.8;(7.0<365.0,位置改变)
第四次内循环
20.0;7.0;7.0;210.5;365.0;7.6;15.6;22.8;(210.5<365.0,位置改变)
第五次内循环
20.0;7.0;7.0;210.5;7.6;365.0;15.6;22.8;(7.6<365.0,位置改变)
第六次内循环
20.0;7.0;7.0;210.5;7.6;15.6;365.0;22.8;(15.6<365.0位置改变)
第七次内循环
20.0;7.0;7.0;210.5;7.6;15.6;22.8;365.0;(22.8<365.0位置改变,找到最大值),即最大值365.0。
第二次外循环(执行6次内循环)
第一次内循环
7.0;20.0;7.0;210.5;7.6;15.6;22.8;365.0;(7.0<20.0,位置改变)
第二次内循环
7.0;7.0;20.0;210.5;7.6;15.6;22.8;365.0;(7.0<20.0,位置改变)
第三次内循环
7.0;7.0;20.0;210.5;7.6;15.6;22.8;365.0;(20.0<210.5,位置不变,接下来就是210.5跟后面的数进行比较)
第四次内循环
7.0;7.0;20.0;7.6;210.5;15.6;22.8;365.0;(7.6<210.5,位置改变)
第五次内循环
7.0;7.0;20.0;7.6;15.6;210.5;22.8;365.0;(15.6<210.5,位置改变)
第六次内循环
7.0;7.0;20.0;7.6;15.6;22.8;210.5;365.0;(22.8<210.5,位置改变,找到第二个值),即第二大值210.5。
第三次外循环(执行5次内循环)
第一次内循环
7.0;7.0;20.0;7.6;15.6;22.8;210.5;365.0;(7.0=7.0,这里的排序就不变,假设第一个值为8.0,8.0>7.0,则位置改变)
第二次内循环
7.0;7.0;20.0;7.6;15.6;22.8;210.5;365.0;(7.0<20.0,位置改变)
第三次内循环
7.0;7.0;7.6;20.0;15.6;22.8;210.5;365.0;(7.6<20.0,位置改变)
第四次内循环
7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0;(15.6<20.0,位置改变)
第五次内循环
7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0;(20.0<22.8,位置不变,找出第三个值),即第三大值22.8。
第四次外循环(执行4次内循环)
第一次内循环
7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0;(7.0=7.0,位置不变)
第二次内循环
7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0;(7.0<7.6,位置不变)
第三次内循环
7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0;(7.6<15.6,位置不变)
第四次内循环
7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0;(15.6<20.0,位置不变,找出第四个值),即最第四大值20.0。
第五次外循环(执行3次内循环)
第一次内循环
7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0;(7.0=7.0,位置不变)
第二次内循环
7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0;(7.0<7.6,位置不变)
第三次内循环
7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0;(7.6<15.6,位置不变,此时找出第五个值),即第五大值15.6。
第六次外循环(执行2次内循环)
第一次内循环
7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0;(7.0=7.0,位置不变)
第二次内循环
7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0;(7.0<7.6,位置不变,此时找出第六个值),即第六大值7.6。
第七次外循环(执行1次内循环)
第一次内循环
7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0;(7.0=7.0,位置不变,此时找出第七个值),即第七大值7.0。
那么最后的那个数显然就是最小值了。
最后由小到大依次排列出来的结果(7.0;7.0;7.6;15.6;20.0;22.8;210.5;365.0)。
其实这是一种冒泡排序法,熟悉计算机语言的小伙伴就应该比较了解这种算法,至于冒泡算法的具体原理和说明,请各位小伙伴自行百度一下,这里就不再赘述了。
程序执行原理:
第一次外循环
第一次内循环
LW8=0,AC1=0*4,AC2=0+4,AC0=0,AC2=4;LD0偏移0和4,即VD1000和VD1004做比较(>),由于VD1000=20.0不大于VD1004=365.0;则程序6不执行,排序不改变(即20.0;365.0;7.0;7.0;210.5;7.6;15.6;22.8;)。
第二次内循环
LW8=1,AC1=1*4,AC2=4+4,AC0=4,AC2=8;LD0偏移4和8,即VD1004和VD1008做比较(>),由于VD1004=365.0>VD1008=7.0;
则程序6执行,*AC1(VD1004=365.0)的值存放到TEMP里(TEMP=365.0),然后*AC2(VD1008=7.0)把值传给*AC1(VD1004=7.0),最后将TEMP的值传给*AC2(VD1008),此时VD1004=7.0,VD1008=365.0,排序发生变化(即20.0;7.0;365.0;7.0;210.5;7.6;15.6;22.8;)。
第三次内循环
LW8=2,AC1=2*4,AC2=8+4,AC0=8,AC2=12;LD0偏移8和12,即VD1008和VD1012做比较(>),由于VD1008=365.0>VD1012=7.0,则程序6执行,*AC1(VD1008=365.0)的值存放到TEMP里(TEMP=365.0),然后*AC2(VD1012=7.0)把值传给*AC1(VD1008=7.0),最后将TEMP的值传给*AC2(VD1012),此时VD1008=7.0,VD1012=365.0,排序发生变化(即20.0;7.0;7.0;365.0;210.5;7.6;15.6;22.8;)。
第四次内循环
LW8=3,AC1=3*4,AC2=12+4,AC0=12,AC2=16;LD0偏移12和16,即VD1012和VD1016做比较(>),由于VD1012=365.0>VD1016=210.5,
则程序6执行,*AC1(VD1012=365.0)的值存放到TEMP里(TEMP=365.0),然后*AC2(VD1016=210.5)把值传给*AC1(VD1012=210.5),最后将TEMP的值传给*AC2(VD1016),此时VD1012=210.5,VD1016=365.0,排序发生变化(即20.0;7.0;7.0;210.5;365.0;7.6;15.6;22.8;)。
第五次内循环
LW8=4,AC1=4*4,AC2=16+4,AC0=16,AC2=20;LD0偏移16和20,即VD1016和VD1020做比较(>),由于VD1016=365.0>VD1020=7.6,
则程序6执行,*AC1(VD1016=365.0)的值存放到TEMP里(TEMP=365.0),然后*AC2(VD1020=7.6)把值传给*AC1(VD1016=7.6),最后将TEMP的值传给*AC2(VD1020),此时VD1016=7.6,VD1020=365.0,排序发生变化(即20.0;7.0;7.0;210.5;7.6;365.0;15.6;22.8;)。
第六次内循环
LW8=5,AC1=5*4,AC2=20+4,AC0=20,AC2=24;LD0偏移20和24,即VD1020和VD1024做比较(>),由于VD1020=365.0>VD1024=15.6,
则程序6执行,*AC1(VD1020=365.0)的值存放到TEMP里(TEMP=365.0),然后*AC2(VD1024=15.6)把值传给*AC1(VD1020=15.6),最后将TEMP的值传给*AC2(VD1024),此时VD1020=15.6,VD1024=365.0,排序发生变化(即20.0;7.0;7.0;210.5;7.6;15.6;365.0;22.8;)。
第七次内循环
LW8=6,AC1=6*4,AC2=24+4,AC0=24,AC2=28;LD0偏移24和28,即VD1024和VD1028做比较(>),由于VD1024=365.0>VD1028=22.8,
则程序6执行,*AC1(VD1024=365.0)的值存放到TEMP里(TEMP=365.0),然后*AC2(VD1028=22.8)把值传给*AC1(VD1024=22.8),最后将TEMP的值传给*AC2(VD1028),此时VD1024=22.8,VD1028=365.0,排序发生变化(即20.0;7.0;7.0;210.5;7.6;15.6;22.8;365.0;)。最后找到了最大值,此时VD1028=365.0。
下面的循环就不在赘述,原理同上。