I am having a course about assembly language, and I bump into this question which is use the loop and xchg instruction to swap all of the element in the array the array look like this The inputStr contains these element “A”, “B”, “C”, “D”, “E”, “F”, “G”, “H”. And after use the loop and xchg, it has to look like this “G”, “H”, “E”, “F”, “C”, “D”, “A”, “B”.
I have already tried to do it many times, but my output is not right. I cannot figure out the logic, or the right way to do this.
This is my code and it is in x86
.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCode: DWORD
.data
inputStr BYTE "A", "B", "C", "D", "E", "F", "G", "H"
.code
main PROC
mov ecx, 8
xor ebx, ebx
mov ebx, offset inputStr
l1:
xor eax, eax
mov al, [ebx]
add ebx, ecx
sub ebx, 2
xchg al, [ebx]
add ebx, 1
sub ebx, ecx
xchg al, [ebx]
inc ebx
dec ecx
loop l1
INVOKE ExitProcess, 0
main ENDP
END main
CodePudding user response:
In an array with N elements, for reversing purposes you can perform N/2 swaps. And if you pair up the elements it's like you started with an array of (N/2) elements, so the number of swaps becomes (N/2)/2.
Apparantly you are required to use the loop
and xchg
instructions. Both are notably slow, so there's also no reason to use the better movzx
in next code:
mov ecx, (8 / 2) / 2 ; Number of swaps
mov ebx, offset inputStr
T1:
mov ax, [ebx] ; Reading a pair
xchg ax, [ebx ecx * 4 - 2] ; Swapping a pair
mov [ebx], ax ; Writing a pair
add ebx, 2
loop T1
What the iterations actually do:
"A", "B", "C", "D", "E", "F", "G", "H"
<---------------- 8 ----------------->
ECX=2 "G", "H", "C", "D", "E", "F", "A", "B"
^ ^
EBX EBX 2 * 4 - 2
^
ECX
"G", "H", "C", "D", "E", "F", "A", "B"
<------ 4 ------->
ECX=1 "G", "H", "E", "F", "C", "D", "A", "B"
^ ^
EBX EBX 1 * 4 - 2
^
ECX
ECX=0
CodePudding user response:
In 64-bit, it could be as simple as:
ITEMS = 8
inputList WORD "A", "B", "C", "D", "E", "F", "G", "H"
mov rbx, inputList
mov ecx, ITEMS/2/2
@@:
mov eax, [rbx]
xchg [rbx rcx*8-4], eax
mov [rbx], eax
add rbx, 4
loop @B
It just produces the desired result by XCHG'ing pairs of 2-byte elements.
From this you should be able to construct the 16-bit variant quite easily using AX instead of RAX.