Home > Software engineering >  Efficiency when swapping array contents
Efficiency when swapping array contents

Time:10-20

I'm new to assembly and I am trying to swap the contents between two arrays. I have this code so far and after testing it, I've verified it works. However, I am wondering if this is the most efficient way to get the desired result or if there is another possible solution to this that is more efficient?

arrW    WORD  100h, 200h, 300h
arrSW   SWORD  -140, 200, -300

mov ax, arrW
xchg ax, arrSW
xchg ax, arrW
mov ax, [arrW  2]
xchg ax, [arrSW  2]
xchg ax, [arrW  2]
mov ax, [arrW   4]
xchg ax, [arrSW  4]
xchg ax, [arrW  4]

CodePudding user response:

mov ax, arrW
xchg ax, arrSW
xchg ax, arrW
mov ax, [arrW  2]

The first thing that struck me is that second xchg. There's no sense in loading the AX register right before the other load of AX in the following instruction. The first rewrite that also gives a 20% speed increase on 8086 therefore is:

mov  ax, [arrW]
xchg ax, [arrSW]
mov  [arrW], ax
mov  ax, [arrW   2]
xchg ax, [arrSW   2]
mov  [arrW   2], ax
mov  ax, [arrW   4]
xchg ax, [arrSW   4]
mov  [arrW   4], ax

A solution where you avoid using the xchg instruction doesn't pay on 8086, but is the way to go on x86 in general. eg. Next snippet is 10% slower on 8086:

mov  ax, [arrW]
mov  bx, [arrSW]
mov  [arrW], bx
mov  [arrSW], ax

A loop can't beat your current unrolled code, but if the arrays should become larger then next is what it could look like:

 mov  cx, 3
 mov  si, OFFSET arrW
 mov  di, OFFSET arrSW
More:
 mov  ax, [si]
 mov  dx, [di]
 mov  [si], dx
 mov  [di], ax
 add  si, 2
 add  di, 2
 dec  cx
 jnz  More

In case the arrays arrW and arrSW follow each other in memory, the same loop is better written as:

 mov  bx, OFFSET arrW
More:
 mov  ax, [bx]
 mov  dx, [bx   6]
 mov  [bx], dx
 mov  [bx   6], ax
 add  bx, 2
 cmp  bx, OFFSET arrSW
 jb   More

If the CPU supports 32-bit registers, then working with these dwords can halve the number of iterations that are required. If the count of elements is odd, we peel off one word sized swap:

 mov  cx, 39
 mov  si, OFFSET arrW
 mov  di, OFFSET arrSW
 shr  cx, 1
 jnc  More             ; Count was even
 mov  ax, [si]
 mov  dx, [di]
 mov  [si], dx
 mov  [di], ax
 add  si, 2
 add  di, 2
More:
 mov  eax, [si]
 mov  edx, [di]
 mov  [si], edx
 mov  [di], eax
 add  si, 4
 add  di, 4
 dec  cx
 jnz  More
  • Related