本文介绍了反转数组程序集的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我试图在程序集中反转数组的元素,这是我的代码: 。data 数组DWORD 1 , 5 , 6 , 8 ,0Ah,1Bh,1Eh,22h,2Ah,32h ;要反转的数组 .code main proc mov esi, 0 mov edi, 0 mov eax, 0 mov ebx, 0 mov esi,OFFSET数组;将第一个元素地址移动到esi mov edi,OFFSET数组+ SIZEOF数组 - TYPE数组;将最后一个元素地址移动到edi mov ecx,LENGTHOF数组/ 2 ;在中设置计数器 reverseLoop reverseLoop: mov eax,[esi];移动元素 in esi to eax mov ebx,[edi];将中的元素 edi移至ebx xchg eax,ebx;交换两个元素 mov [esi],eax;将元素移动到 eax中,移动到地址中的class =code-keyword> esi mov [edi],ebx;将中的元素移动到 ebx中,地址为 edi 添加 esi,TYPE数组;增加esi以获取下一个元素 in 数组(来自左侧) sub edi,TYPE数组;减少edi以取得数组中的下一个元素(来自右侧) loop reverseLoop 调用ExitProcess, 0 main endp end main < / pre > 此代码到目前为止使用DWORD数组,但是,如果我将数组的大小更改为BYTE我会遇到问题。在reverseLoop的第一行中,mov eax,[esi],当数组的大小为DWORD时,eax寄存器不会像数组中的第一个元素一样获取数据。相反,它似乎得到一些随机数。任何想法为什么这样做? 我尝试过: 我无法弄清楚问题是什么。解决方案 首先,你可以简化你的代码 reverseLoop: mov eax,[esi];将esi中的元素移动到eax mov ebx,[edi];将edi中的元素移动到ebx xchg eax,ebx;交换两个元素 mov [esi],eax;将eax中的元素移动到esi mov [edi]中的地址,ebx;移动元素在ebx中,到edi 的地址添加esi,TYPE数组;增加esi以获取数组中的下一个元素(从左边开始) sub edi,TYPE数组;将edi减少到获取数组中的下一个元素(从右边开始) loop reverseLoop by reverseLoop: mov eax,[esi];将esi中的元素移动到eax mov ebx,[edi];将edi中的元素移动到e bx xchg eax,ebx;交换两个元素 mov [esi], ebx ;移动元素在 ebx 中,到esi mov [edi], eax 中的地址;将 eax 中的元素移动到地址中edi 添加esi,TYPE数组;增加esi以获取数组中的下一个元素(从左侧开始) sub edi,TYPE数组;减少edi以获取数组中的下一个元素(右起) loop reverseLoop 其次,为什么不使用字节大小的寄存器来移动字节? 喜欢 AL 或 AH 和 BL 或 BH ? 我知道,这是老式的,但它对我来说最直接。 [更新] 为了尽可能快地处理所有可能性,你需要一些代码,如: if (TYPE为DWORD)优化代码 for DWORD(主要是你的示例代码) else if (TYPE是WORD )优化代码 for WORD else if (TYPE为BYTE)优化代码 BYTE end if 要使用单段代码处理所有可能性,您必须以尽可能小的数据大小运行。这可能会很慢。 数组DWORD 1,2,3,4,5,6,7,8,9,10,11,12 将给予 数组DWORD 9,10,11,12,5,6,7,8, 1,2,3,4 数组WORD 1,2,3,4,5, 6,7,8,9,10,11,12 将给出 数组WORD 11, 12,9,10,7,8,5,6,3,4,1,2 阵列BYTE 1,2,3,4,5,6,7,8,9,10,11,12 将给予 数组BYTE 12,11,10,9,8,7,6,5,4,3,2,1 在你的主循环中,你需要另一个循环来处理不同的数据大小。 reverseLoop: for dx = 1 to(TYPE array) mov啊,[esi];将esi中的元素移动到啊 mov bh,[edi];将edi中的元素移动到bh mov [esi],bh;移动 bh 中的元素,到esi mov [edi]中的地址,啊;将啊中的元素移动到地址在edi 添加esi,1 添加esi,1 下一个 sub edi,TYPE数组 sub edi,TYPE数组;减少edi以获取下一个元素在数组中(从右边) 循环reverseLoop 伪代码,我让你处理细节 mov eax,[esi] 加载带有DWORD值的eax,而不是字节。 这是一个真正的问题,因为字节指针不仅限于DWORD地址。 DWORD总是在一个4的倍数的地址上,字节地址是一个多个一个。因此,当您将字节地址传递给DWORD指令时,加载的值不是一个字节,并且不是从该地址开始的四个字节。它是从字节地址向下舍入到前四个倍数的四个字节。 所以它看起来像随机数据,但它不是! 使用字节访问字节数据。 mov esi,0 mov edi,0 mov eax,0 mov ebx,0 mov esi,OFFSET数组;将第一个元素地址移动到esi mov edi,OFFSET数组;移动最后一个元素地址to edi mov ecx,LENGTHOF数组;在counterLoop中设置计数器 reverseLoop: mov eax,[esi];将esi中的元素移动到eax mov ebx,[edi];将edi中的元素移动到ebx 添加esi,TYPE数组;增加esi以获取数组中的下一个元素(从左侧开始) sub edi,TYPE数组;减少edi以获取数组中的下一个元素(从右侧开始) 调用writehex 调用crlf loop reverseLoop Hi,I am trying to reverse the element of an array in assembly, here is my code:.dataarray DWORD 1, 5, 6, 8, 0Ah, 1Bh, 1Eh, 22h, 2Ah, 32h ;array to be reversed.codemain proc mov esi, 0mov edi, 0mov eax, 0mov ebx, 0mov esi, OFFSET array;move first element address to esimov edi, OFFSET array + SIZEOF array - TYPE array ;move last element address to edimov ecx, LENGTHOF array / 2 ;sets the counter in the reverseLoopreverseLoop:mov eax, [esi] ;move the element in esi to eaxmov ebx, [edi] ;move the element in edi to ebxxchg eax, ebx ;exchange the two elementsmov [esi], eax ;move the element in eax, to the address in esimov [edi], ebx ;move the element in ebx, to the address in ediadd esi, TYPE array ;increase esi to take the next element in the array (from the left)sub edi, TYPE array ;decrease edi to take the next element in the array (from the right)loop reverseLoopinvoke ExitProcess,0main endpend main</pre>This code works so far with DWORD array, however, if i change the size of the array to BYTE i get a problem. In the first line in reverseLoop, "mov eax, [esi]", the eax register does not get the first element in the array as it used to when the size of the array was DWORD. Instead it seems to get some random number. Any ideas why it is doing that?What I have tried:I could not really figure out what the problem is. 解决方案 First of all, you can simplify your codereverseLoop:mov eax, [esi] ;move the element in esi to eaxmov ebx, [edi] ;move the element in edi to ebxxchg eax, ebx ;exchange the two elementsmov [esi], eax ;move the element in eax, to the address in esimov [edi], ebx ;move the element in ebx, to the address in ediadd esi, TYPE array ;increase esi to take the next element in the array (from the left)sub edi, TYPE array ;decrease edi to take the next element in the array (from the right)loop reverseLoopbyreverseLoop:mov eax, [esi] ;move the element in esi to eaxmov ebx, [edi] ;move the element in edi to ebxxchg eax, ebx ;exchange the two elementsmov [esi], ebx ;move the element in ebx, to the address in esimov [edi], eax ;move the element in eax, to the address in ediadd esi, TYPE array ;increase esi to take the next element in the array (from the left)sub edi, TYPE array ;decrease edi to take the next element in the array (from the right)loop reverseLoopSecond, why don't you use byte sized registers to move bytes ?Like AL or AH and BL or BH ?I know, it is old fashioned, but it look the most straight forward to me.[Update]To handle all possibilities as fast as possible, you need some code like:if (TYPE is DWORD) optimized code for DWORD (mostly your sample code)else if (TYPE is WORD) optimized code for WORDelse if (TYPE is BYTE) optimized code for BYTEend ifTo handle all possibilities with a single piece of code, you must operate at smallest possible data size. It is possible but will be slow.array DWORD 1,2,3,4,5,6,7,8,9,10,11,12will givearray DWORD 9,10,11,12,5,6,7,8,1,2,3,4array WORD 1,2,3,4,5,6,7,8,9,10,11,12will givearray WORD 11,12,9,10,7,8,5,6,3,4,1,2array BYTE 1,2,3,4,5,6,7,8,9,10,11,12will givearray BYTE 12,11,10,9,8,7,6,5,4,3,2,1in your main loop, you need another loop to handle the different data sizes.reverseLoop: for dx=1 to (TYPE array) mov ah, [esi] ;move the element in esi to ah mov bh, [edi] ;move the element in edi to bh mov [esi], bh ;move the element in bh, to the address in esi mov [edi], ah ;move the element in ah, to the address in edi add esi, 1 add esi, 1 next sub edi, TYPE array sub edi, TYPE array ;decrease edi to take the next element in the array (from the right) loop reverseLoopPseudo code, I let you deal with detailsmov eax, [esi]loads eax with a DWORD value, not a byte.And that's a real problem, because byte pointers aren't limited to DWORD addresses.DWORDs are always on an address which is a multiple of 4, byte addresses are a multiple of one. So when you pass a byte address to a DWORD instruction, the value loaded is not a byte, and it's not four bytes starting at that address. It's four bytes starting from the byte address rounded down to the previous multiple of four.So it looks like random data, but it isn't!Use byte access with byte data.mov esi, 0mov edi, 0mov eax, 0mov ebx, 0mov esi, OFFSET array ;move first element address to esimov edi, OFFSET array ;move last element address to edimov ecx, LENGTHOF array ;sets the counter in the reverseLoopreverseLoop:mov eax, [esi] ;move the element in esi to eaxmov ebx, [edi] ;move the element in edi to ebxadd esi, TYPE array ;increase esi to take the next element in the array (from the left)sub edi, TYPE array ;decrease edi to take the next element in the array (from the right) call writehex call crlfloop reverseLoop 这篇关于反转数组程序集的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-05 06:38