反转数组程序集的元素 [英] Reversing elements of an array assembly

查看:81
本文介绍了反转数组程序集的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





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



。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以获取下一个元素< span class =code-keyword> 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


这篇关于反转数组程序集的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆