装入(Load,L)指令将源操作数装入累加器1,而累加器1原有的数据移入累加器2。
装入指令可以对字节(8位)、字(16位)、双字(32位)数据迸行操作。
传送(Transfer,T)指令将累加器1中的内容写入目的存储区中,累加器1的内容不变。
1.立即寻址的装入与传送指令
立即寻址的操作数直接在指令中。
【实例】 使用立即寻址的例子。
L-35 //将16位十进制常数-35装入累加器1的低字ACCU1-L
L L#5 //将32位常数5装入累加器1
L B#16#5A //将8位十六进制常数装入累加器1最低字节ACCU1-LL
L W#16#3E4F //将16位十六进制常数装入累加器1的低字ACCU1-L
L DW#16#567A3DC8 //将32位十六进制常数装入累加器1
L 2#0001_1001_1110_0010 //将16位二进制常数装入累加器1的低字ACCU1-L
L 25.38 //将32位浮点数常数(25.38)装入累加器1
L ‘ABCD’ //将4个字符装入累加器1
L TOD#12:30:3.0 //将32位实时时间常数装入累加器1
L D#2004-2-3 //将16位日期常数装入累加器1的低字ACCU1-L
L C#50 //将16位计数器常数装入累加器1的低字ACCU1-L
L T#1M20S //将16位定时器常数装入累加器1的低字ACCU1-L
L S5T#2S //将16位定时器常数装入累加器1的低字ACCU1-L
L P#M5.6 //将指向M5.6的指针装入累加器1
L B#(100,12,50,8) //装入4字节无符号常数
2.直接寻址的装入与传送指令
直接寻址在指令中直接给出存储器或寄存器的区域、长度和位置,例如用MW200指定位存储区中的字,地址为200。
【实例】 直接寻址的程序实例:
A I0.0 //输入位I0.0的“与”(AND)操作
L MB10 //将8位存储器字节装入累加器1最低的字节ACCU1-LL
L DIW15 //将16位背景数据字装入累加器1的低字ACCU1-L
L LD22 //将32位局域数据双字装入累加器1
T QB10 //将ACCU1-LL中的数据传送到过程映像输出字节QB10
T MW14 //将ACCU1-L中的数据传送到存储器字MW14
T DBD2 //将ACCU1中的数据传送到数据双字DBD2
3.寄存器间接寻址
在存储器间接寻址指令中,给出一个作地址指针的存储器,该存储器的内容是操作数所在存储单元的地址。在循环程序中经常使用存储器间接寻址。
地址指针可以是字或双字,定时器(T)、计数器(C)、数据块(DB)、功能块(FB)和功能(FC)的编号范围小于65535,使用字指针就够了。
其他地址则要使用双字指针,如果要用双字格式的指针访问一个字、宇节或双字存储器,必须保证指针的位编号为0,例如P#Q20.0。
L QB[DBD 10] //将输出字节装入累加器1,输出字节的地址指针在数据双字
//DBD10中;如果DBD10的值为2#00000000000000000000
//000000100000,装入的是QB4
A M[LD 4] //对存储器位作“与”运算,地址指针在数据双字LD4中。如果
//LD4的值为2#00000000000000000000000000100011,
//则是对M4.3进行操作
存储器间接寻址的双字指针格式如图3-17所示,共有两种。
图3-17 存储器间接寻址的双字指针格式
其中第0~2位(xxx)为被寻址地址中位的编号(0~7),第3~18位为被寻址地址的字节的编号(0~65535)。第24~26位(rrr)为被寻址地址的区域标识号,第31位x=0为区域内的间接寻址,第31位x=1为区域间的间接寻址。
第一种地址指针格式存储区的类型在指令中给出,例如L DBB[AR1,P#6.0]。在某一存储区内寻址。第24~26位(rrr)应为0。
第二种地址指针格式的第24~26位还包含存储区域标识符rrr,为区域间寄存器间接寻址。表3-2为寄存器间接寻址的区域标识位。
如果要用寄存器指针访问一个字节、字或双字,必须保证指针中的位地址编号为0。
指针常数#P5.0对应的二进制数为2#0000 0000 0000 0000 0000 0000 0010 1000。
【实例】 区域内间接寻址的例子。
L P#5.0 //将间接寻址的指针装入累加器1
LAR1 //将累加器1中的内容送到地址寄存器1
表3-2 寄存器间接寻址的区域标识位
A M[AR1,P#2.3] //AR1中的P#5.0加偏移量P#2.3,实际上是对M7.3进行操作
= Q[AR1,P#0.2] //逻辑运算的结果送Q5.2
L DBW[AR1,P#18.0] //将DBW23装入累加器1
【实例】 区域间间接寻址的例子。
L P#M6.0 //将存储器位M6.0的双字指针装入累加器1
LAR1 //将累加器1中的内容送到地址寄存器1
T W[AR1,P#50.0] //将累加器1的内容传送到存储器字MW56
P#M6.0对应的二进制数为2#1000 0011 0000 0000 0000 0000 0011 0000。因为地址指针P#M6.0中已经包含有区域信息,使用间接寻址的指令T W[AR1,P#50]中没有必要再用地址标识符M。
4.地址寄存器的装入与传送指令
用地址寄存器的装入与传送指令可以不经过累加器1,与地址寄存器AR1和AR2交换数据。
【实例】 应用地址寄存器AR1和AR2的实例。
LAR1 DBD20 //将数据双字DBD20中的指针装入AR1
LAR2 LD180 //将局域数据双字LD180中的指针装入AR2
LAR1 P#M10.2 //将带存储区标识符的32位指针常数装入AR1
LAR2 P#24.0 //将不带存储区标识符32位指针常数装入AR2
TAR1 DBD20 //AR1中的内容传送到数据双字DBD20
TAR2 MD24 //AR2中的内容传送到存储器双字MD24
表3-3为比较指令的STL表达方式,表中“?”可以是“==”,“<>”,“>”,“<”“>=”,“<=”。
用于比较累加器1与累加器2中的数据大小,被比较的两个数的数据类型应该相同。如果比较的条件满足,则RLO为1,否则为0。状态字中的CC0和CC1位用来表示两个数的大于、小于和等于关系(见表3-4)。
【实例】 比较两个浮点数的例子:
表3-3 比较指令
表3-4 指令执行后的CC1和CC0
L MD4 //MD4中的浮点数装入累加器1
L 2.345E+02 //浮点数常数装入累加器1,MD4装入累加器2
>R//比较累加器1和累加器2的值
=Q4.2//如果MD4>2.345E+02,则Q4.2为1
表3-5所示为数据转换指令,其中3位BCD码和7位BCD码的格式如图3-18所示。
表3-5 数据转换指令
【实例】 双整数转换为BCD码的例子。
A I0.2 //如果I0.2为1
L MD10 //将MD10中的双整数装入累加器1
DTB //将累加器1中的数据转换为BCD码,结果仍在累加器1中
图3-18 BCD码格式
a)3位BCD码的格式 b)7位BCD码的格式
JO OVER //运算结果超出允许范围(OV=1)则跳转到标号OVER处
T MD20 //将转换结果传送到MD20
A M4.0
R M4.0 //复位溢出标志
JU NEXT //无条件跳转到标号NEXT处
OVER:AN M4.0
S M4.0 //置位溢出标志
NEXT:……
【实例】 将101英寸(in)转换为以厘米(cm)为单位的整数,送到MW0中。
L 101 //将16位常数101(65H)装入累加器1
ITD //转换为32位双整数
DTR //转换为浮点数101.0
L 2.54 //浮点数常数2.54装入累加器1,累加器1的内容装入累加器2
*R //101.0乘以2.54,转换为256.54厘米
RND //四舍五入转换为整数257(101H)
T MW30
表3-6所示为取反与求补指令的STL表达方式。
表3-6 取反与求补指令
【实例】 求补应用例子。
L MD20 //将32位双整数装入累加器1
NEGD //求补
T MD30 //运算结果传送到MD30
表3-7为整数数学运算指令的STL表达式,表3-8为浮点数数学运算的STL表达式。图3-19所示为数学运算的累加器变化。需要注意的是,语句表中“*I”指令的运算结果为32位整数,梯形图中MUL_I指令的运算结果为16位整数。
表3-7 整数数学运算指令
表3-8 浮点数数学指令
【实例】 用浮点数对数指令和指数指令求5的立方。
计算公式:5 3 =EXP(3*LN(5))=125
L L#5
DTR
LN
L 3.0
*R
EXP
RND
T MW40
图3-19 数学运算的累加器变化
表3-9为移位指令,它对累加器1中的数操作,结果在累加器1中。需要注意的是:用指令中的参数<number>来指定移位位数,16位移位指令为0~15,32位移位指令为0~32。如果<number>等于0,移位指令被当作NOP(空操作)指令来处理;如果指令没有参数<number>,移位位数放在累加器2的最低字节中(0~255),而如果移位位数等于0,移位指令被当作NOP(空操作)指令来处理。一旦有符号字的移位位数>16时,移位后被移位的数的各位全部变成了符号位。
表3-9 移位指令
【实例】 整数移位应用(结果见表3-10)。
L MW4 //将MW4的内容装入累加器1的低字中
SSI 6 //累加器1低字中的有符号数右移6位,结果仍在累加器1的低字中
T MW8 //累加器1低字中的运算结果传送到MW8中
表3-11为字逻辑运算指令的STL表达方式。表3-12给出了累加器1和累加器2进行字逻辑运算后的结果。
表3-10 整数右移6位前后的数据
表3-11 字逻辑运算指令的STL表达方式
表3-12 字逻辑运算的结果
【实例】 字或运算应用。
L QW10 //QW10的内容装入累加器1的低字中
L W#16#000F //累加器1的内容装入累加器2,W#16#000F装入累加器1的低字中
OW //累加器1低字与W#16#000F逐位相或,结果在累加器1的低字中
T QW10 //累加器1低字中的运算结果传送到QW10中
表3-13为累加器指令,也是在STL编程中应用最为广泛的一个指令之一,其中图3-20所示演示了入栈和出栈执行前后的变化。
【实例】 用语句表程序实现浮点数运算(DBD0+DBD4)/(DBD8-DBD12)。
L DBD0 //DBD0中的浮点数装入累加器1
L DBD4 //累加器1的内容装入累加器2,DBD4中的浮点数装入累加器1
+R //累加器1,2中的浮点数相加,结果保存在累加器1中
L DBD8 //累加器1的内容装入累加器2,DBD8中的浮点数装入累加器1
ENT //累加器3的内容装入累加器4,累加器2的中间结果装入累加器3
L DBD12 //累加器1的内容装入累加器2,DBD12中的浮点数装入累加器1
-R/ /累加器2的内容减去累加器1的内容,结果保存在累加器1中
LEAVE //累加器3的内容装入累加器2,累加器4的中间结果装入累加器3
/R //累加器2的(DBD0+DBD4)除以累加器1的(DBD8-DBD12)
T DBD16 //累加器1中的运算结果传送到DBD16
表3-13 累加器指令
图3-20 入栈和出栈执行前后的变化
a)入栈指令执行前后 b)出栈指令执行前后
表3-14所示为逻辑控制指令的STL表达方式,很多逻辑控制指令在梯形图中不一定会有,这一点需要读者注意。逻辑控制跳转中,只能在同一逻辑块内跳转;同一个跳转目的地址只能出现一次;跳转或循环指令的操作数为地址标号,标号由最多4个字符组成,第一个字符必须是字母,其余的可以是字母或数字。
这里对LOOP特别说明如下:循环指令LOOP<jump label>用ACCU 1-L作循环计数器,每次执行LOOP指令时ACCU 1-L的值减1,若减1后ACCU 1-L非0,将跳转到<jump label>指定的标号处。
表3-14 逻辑控制指令
【实例】 IW8与MW12的异或结果如果为0,将M4.0复位,非0则将M4.0置位。
L IW8 //IW8的内容装入累加器1的低字
L MW12 //累加器1的内容装入累加器2,MW12的内容装入累加器1
XOW //累加器1,2低字的内容逐位异或
JN NOZE //如果累加器1的内容非0,则跳转到标号NOZE处
R M4.0
JU NEXT
NOZE:AN M4.0
S M4.0
NEXT:NOP 0
【实例】 用循环指令求5!(5的阶乘)。
L L#1 //32位整数常数装入累加器1,置阶乘的初值
T MD20 //累加器1的内容传送到MD20,保存阶乘的初值
L 5 //循环次数装入累加器的低字中
BACK:T MW10 //累加器1低字的内容保存到循环计数器MW10
L MD20 //取阶乘值
*D //MD20与MW10的内容相乘
T MD20 //乘积送MD20
L MW10 //循环计数器内容装入累加器1
LOOP BACK //累加器1低字的内容减1,减1后非0,跳到标号BACK
……//循环结束后,恢复线性扫描
程序控制指令见表3-15。
表3-15 程序控制指令
数据块指令见表3-16。
表3-16 数据块指令
【实例】 数据块指令应用。
OPN DB10 //打开数据块DB10作为共享数据块
L DBW35 //将打开的DB10中的数据字DBW35装入累加器1的低字中
T MW12 //累加器1低字的内容装入MW12
OPN DI20 //打开作为背景数据块的数据块DB20
L DIB35 //DB20.DIB35装入累加器1的最低字节中
T DBB27 //累加器1最低字节传送到DB10.DBB27