技术论坛

 回复:怎样实现64位循环左移?(转)

返回主题列表
作者 主题
留恋你的气息
游士

经验值:240
发帖数:70
精华帖:0
楼主    2011-04-04 10:07:01
主题:怎样实现64位循环左移?(转)
本文转自廖老师的博客
S7-300/400只有32位的循环移位指令,和32位加CC1的循环移位指令。下面是我编的程序,MD10和MD14组成64位数据,MD10在高32位。
在I0.0的上升沿,分别将MD10和MD14循环左移1位,然后交换它们的最低位M13.0和M17.0的值,就能实现64位数据的循环左移1位。
A I 0.0
FN M 1.0
JCN _001 //不是I0.0的上升沿则跳转
L MD 10
RLD 1 //双字左移一位
T MD 10
L MD 14
RLD 1 //双字左移一位
T MD 14
A M 13.0
= M 1.1 //暂存M13.0
A M 17.0
S M 13.0 //以下程序交换M13.0和M17.0的值
AN M 17.0
R M 13.0
A M 1.1
S M 17.0
AN M 1.1
R M 17.0
_001: NOP 0
此程序已用仿真验证,下图中的修改数值是移位之前MD10和MD14的值,状态值是循环左移4位后的值。
以上观点纯属个人意见,如有误解,请各位给予指正,多谢!
姑苏城外
侠圣

经验值:3598
发帖数:1466
精华帖:19
66楼    2011-06-29 00:25:46
精华帖  主题:回复:怎样实现64位循环左移?(转)
quote:以下是引用Zane在2011-04-05 00:19:00的发言:
我出一题吧:

N>3 的任意位数的循环移位。
以前正好做过一个,翻出来,加了一个用ENO判断移位是否正确执行.
合法移位0<=N<=63,程序如下:

FUNCTION "Shift_64bits" : VOID
TITLE =
AUTHOR : SXG
FAMILY : Shift
NAME : Shift_64
VERSION : 1.0


VAR_INPUT
X_Dword1 : DWORD ;
X_Dword2 : DWORD ;
X_ShiftNumber : INT ; //0 <= X_ShiftNumber <= 63
END_VAR
VAR_OUTPUT
Q_Shifted1 : DWORD ;
Q_Shifted2 : DWORD ;
END_VAR
VAR_TEMP
L_InputDword1 : DWORD ;
L_InputDword2 : DWORD ;
L_OutputDword1 : DWORD ;
L_OutputDword2 : DWORD ;
L_ShiftNumberDINT : DINT ;
L_InputAddress : DINT ;
L_OutputAddress : DINT ;
END_VAR
BEGIN
NETWORK
TITLE =

L #X_ShiftNumber;
L 63;
>I ;
JC err;

L #X_Dword1;
T #L_InputDword1;
L #X_Dword2;
T #L_InputDword2;
L #X_ShiftNumber;
ITD ;
T #L_ShiftNumberDINT;

L L#0;
T #L_InputAddress;

m001: A L [#L_InputAddress];
L #L_ShiftNumberDINT;
L L#64;
+D ;
T #L_OutputAddress;
= L [#L_OutputAddress];

L #L_InputAddress;
L L#1;
+D ;
T #L_InputAddress;
L 64;
>=D ;
JC end;
L #L_ShiftNumberDINT;
L L#1;
+D ;
T #L_ShiftNumberDINT;
L 64;
>=D ;
JCN m001;
TAK ;
-D ;
T #L_ShiftNumberDINT;
JU m001;
err: CLR ;
SAVE ;
BE ;
end: L #L_OutputDword1;
T #Q_Shifted1;
L #L_OutputDword2;
T #Q_Shifted2;
SAVE ;
BE ;
END_FUNCTION

与人规矩,不与人巧!
划痕
侠圣

经验值:4794
发帖数:2009
精华帖:22
95楼    2011-11-09 17:10:07
精华帖  主题:回复:怎样实现64位循环左移?(转)
看了大家的程序,感觉都是太长了,不直观也不够技巧!(感觉大家没有拿出真本事哦)
今天动手做了一个小程序,可以实现N>2位数据顺序左移x位(x小于N),在此与大家分享一下!
<欢迎拍砖,如果你还能做的更简单那就更好啦 ^_^ >
程序中只用了一个地址指针,使用了间接寻址,强化了对temp堆栈区的使用;以下例程能实现N<64位的任意位数的左移x位的功能,只要稍加修改就能实现在65536位数的左移功能!
FUNCTION "Shiftbit" : VOID
TITLE =
VERSION : 0.1

VAR_INPUT
count : INT ; //the number of bits
db_num : BLOCK_DB ; //DB No.
shift_num : INT ; //number of shift
END_VAR
VAR_TEMP
temp1 : DWORD ; //save 32 bits
temp2 : DWORD ; //save 32 bits
temp3 : INT ; //count
temp4 : BOOL ; //save signal
temp5 : DINT ; //address pointer
END_VAR
BEGIN
NETWORK
TITLE =
OPN #db_num;
L #shift_num;
L -1;
+I ;
LAR1 ; //初始化AR1
L L#0; //初始化地址指针
T #temp5;
L DBD 0; //数据暂存起来
T #temp1;
L DBD 4;
T #temp2;
L #count; //计数总位数
next: T #temp3;
A L [#temp5]; //取出第temp5位
= #temp4; //暂存起来
L #temp5;
L 1;
+I ;
T #temp5; //地址指针指向下一位(temp5=temp5+1)
TAR1 ;
L 1; //移位地址指针(偏移量)
+I ; //偏移量是否超过总的位数
LAR1 ;
TAR1 ;
L #count;
JCN _001;
JU _002;
_001: L L#0; //超过总位数清零
LAR1 ;
_002: A #temp4;
= DBX [AR1,P#0.0]; //送达目的地
L #temp3;
LOOP next; //剩余移位计数
SET ;
SAVE ;
BE ;
END_FUNCTION
欢迎测试,以下提供源代码下载!
点击此处查看附件
No discussion, no outcome.
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。