反转数组程序集的元素

编程入门 行业动态 更新时间:2024-10-19 15:26:28
本文介绍了反转数组程序集的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我试图在程序集中反转数组的元素,这是我的代码:

。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:

.data array DWORD 1, 5, 6, 8, 0Ah, 1Bh, 1Eh, 22h, 2Ah, 32h ;array to be reversed .code main proc mov esi, 0 mov edi, 0 mov eax, 0 mov ebx, 0 mov esi, OFFSET array ;move first element address to esi mov edi, OFFSET array + SIZEOF array - TYPE array ;move last element address to edi mov ecx, LENGTHOF array / 2 ;sets the counter in the reverseLoop reverseLoop: mov eax, [esi] ;move the element in esi to eax mov ebx, [edi] ;move the element in edi to ebx xchg eax, ebx ;exchange the two elements mov [esi], eax ;move the element in eax, to the address in esi mov [edi], ebx ;move the element in ebx, to the address in edi add 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 reverseLoop invoke ExitProcess,0 main endp end 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 code

reverseLoop: mov eax, [esi] ;move the element in esi to eax mov ebx, [edi] ;move the element in edi to ebx xchg eax, ebx ;exchange the two elements mov [esi], eax ;move the element in eax, to the address in esi mov [edi], ebx ;move the element in ebx, to the address in edi add 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 reverseLoop

by

reverseLoop: mov eax, [esi] ;move the element in esi to eax mov ebx, [edi] ;move the element in edi to ebx xchg eax, ebx ;exchange the two elements mov [esi], ebx ;move the element in ebx, to the address in esi mov [edi], eax ;move the element in eax, to the address in edi add 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 reverseLoop

Second, 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 WORD else if (TYPE is BYTE) optimized code for BYTE end if

To 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,12

will give

array DWORD 9,10,11,12,5,6,7,8,1,2,3,4

array WORD 1,2,3,4,5,6,7,8,9,10,11,12

will give

array WORD 11,12,9,10,7,8,5,6,3,4,1,2

array BYTE 1,2,3,4,5,6,7,8,9,10,11,12

will give

array BYTE 12,11,10,9,8,7,6,5,4,3,2,1

in 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 reverseLoop

Pseudo code, I let you deal with details

mov 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, 0 mov edi, 0 mov eax, 0 mov ebx, 0 mov esi, OFFSET array ;move first element address to esi mov edi, OFFSET array ;move last element address to edi mov ecx, LENGTHOF array ;sets the counter in the reverseLoop reverseLoop: mov eax, [esi] ;move the element in esi to eax mov ebx, [edi] ;move the element in edi to ebx add 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 crlf loop reverseLoop

更多推荐

反转数组程序集的元素

本文发布于:2023-11-29 12:47:18,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1646433.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数组   元素   程序

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!