Home > OS >  Use loop and xchg instruction in assembly language to swap the element in the array
Use loop and xchg instruction in assembly language to swap the element in the array

Time:11-12

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.

  • Related