首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何编辑它,使数组移位2位?例如。最后的数组是30,40,10,20

如何编辑它,使数组移位2位?例如。最后的数组是30,40,10,20
EN

Stack Overflow用户
提问于 2019-10-25 12:15:18
回答 1查看 44关注 0票数 1

我想将数组移位一个DWORD变量2,这样最终的数组就是30,40,10,20

我想支持可变长度的数组

代码语言:javascript
运行
复制
.data
array DWORD 10,20,30,40
arrayType DWORD TYPE array
newArray DWORD LENGTHOF array DUP(?)
lastElement DWORD ?

.code
main PROC

;Get first element address in ESI
MOV ESI, OFFSET array

;Get address of next element in EDI
MOV EDI, OFFSET newArray
ADD EDI, TYPE newArray

;set loop count into ecx
mov ECX, LENGTHOF array

L2:
MOV EAX, [ESI]
MOV [EDI], EAX

ADD ESI, TYPE array
ADD EDI, TYPE array

LOOP L2

;set last element from array in newArray first position
MOV EDI,OFFSET newArray
MOV EAX, [ESI]
MOV [EDI], EAX
EN

回答 1

Stack Overflow用户

发布于 2019-10-25 13:46:33

你正在写一个单独的目的地,所以在读和写之间没有重叠。这使得它变得非常简单:从一个数组的第一个循环到最后一个数组,然后从另一个数组的中间开始换行。

例如,从目的地的第一个元素开始,并使用分支有条件地从src指针减去长度(以字节为单位)。(与cmov相比,分支是一个很好的选择,因为它只会为真一次;每隔一次您就会正常地循环一次)。

或者拆分你的循环,复制成两个块:从src的中间到结尾,然后从开始到中间。

您甚至可以对此使用两次rep movsd,而不是循环,保留edi不变以继续附加目标,但将esi重置为从源开始读取。(如果您不打算使用单指令多数据向量,对于10个或更多元素,rep movsd比一次4字节的复制循环更快。或者使用slow-on-Intel loop指令,盈亏平衡点更低。)

对于固定大小的问题,您当然可以将整个内容加载到4个寄存器中,或者使用SSE2 movdqu-load / pshufd / movdqu-store来混洗16字节SIMD向量的双字块。

如果你必须就地旋转(更新一个数组,而不是制作一个修改过的副本),你可以使用几个临时寄存器在可变长度上硬编码“旋转2个位置”部分,以处理写入和读取之间的重叠。

我不打算发布代码,因为这看起来像家庭作业,如果不解决它,我就不能展示一个例子。

但是arrayType DWORD TYPE array看起来不是个好主意。TYPE array是一个汇编时间常量;您不希望将其存储在内存中并将其作为数据加载,只需像使用ADD ESI, TYPE array一样将其用作立即数即可

lastElement DWORD ?也未被使用,这也是一件好事。使用寄存器(直到用完为止)作为单字块的暂存空间。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58552116

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档