Click here to Skip to main content
15,881,803 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I am trying to reverse the element of an array in assembly, here is my code:

C#
.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.
Posted
Updated 24-Nov-17 16:24pm
Comments
PIEBALDconsult 11-Jun-16 17:57pm    
You should not have deleted the original version of this question; you should have used "Improve question".
Member 12569032 11-Jun-16 18:05pm    
I did, but I accidently deleted the question and then tried to improve, but then saw that it was deleted.

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:
C++
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
 
Share this answer
 
v4
Comments
Member 12569032 11-Jun-16 19:11pm    
In my assignment my code is suppose to work for any size of array
Patrice T 11-Jun-16 19:16pm    
Size of array or size of elements ?
Member 12569032 11-Jun-16 19:24pm    
Size of elements i mean. Each element in the array could be of any size, BYTE or DWORD depending on what size you declare the array.
Karthik_Mahalingam 12-Jun-16 2:21am    
5
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.
 
Share this answer
 
Comments
Member 12569032 11-Jun-16 17:52pm    
Any ideas how to make the code work for any size of array?
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
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900