News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

I need help understanding the XCHG instruction

Started by RedSkeleton007, July 12, 2015, 04:36:39 AM

Previous topic - Next topic

RedSkeleton007

In my text book, (minus my code comments), it says:

--------
To exchange two memory operands, use a register as a temporary container and combine MOV with XCHG:


mov ax, val1 ;store val1 into reg ax
xchg ax, val2 ;swap val2 with ax
mov val1, ax ;store ax register's contents into val1

--------

In line 2, (assuming ax still has val1 stored in it), does xchg simply mean that ax becomes the source and val2 becomes the destination? Or is val2 supposed to remove val1 out of reg ax and take its place so that val1 can still exist in memory somewhere outside of reg ax?

dedndave

for the XCHG instruction, both operands are both source and destination, in a manner of speaking
that's the nature of the instruction

but - the rule is that both operands may not be memory operands
this rule is true for most instructions

XCHG is short for "exchange" - it swaps the two operand values

dedndave

i might mention that XCHG is somewhat slow when one of the operands is in memory   :P
it's very fast, though, if both operands are in registers

Tedd

XCHG AX,BX copies the value of AX into BX, and the value of BX (before AX was copied there) into AX -- exchanging the values of the two operands in a single instruction. Pseudo code would be: tmp = src; src = dst; dst = tmp

It works the same way if one of the operands is a memory location.
Your book is showing an example of exchanging the contents of two memory locations, which can't be done in a single operation (there is no XCHG mem,mem), and so they are using XCHG to swap the values of the register and memory.


Not that it's particularly relevant, but since Dave mentioned it, the reason XCHG is 'slow' when one operand is memory is because it causes a memory bus lock so the read and write of the memory location can be completed atomically (which delays other instructions from accessing memory until this one finishes.)
Potato2

hutch--

You can do it on the stack.


main proc

    LOCAL var1  :DWORD
    LOCAL var2  :DWORD

    mov var1, 100
    mov var2, 200

    push var2
    push var1
    pop var2
    pop var1

    print str$(var1),13,10
    print str$(var2),13,10

    ret

main endp


Here is a test piece with more options on how to swap 2 32 bit values.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    .data?
      value dd ?

    .data
      item dd 0

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    LOCAL var1  :DWORD
    LOCAL var2  :DWORD

    push ebx
    push esi
    push edi

  ; ------------------------

    mov var1, 100
    mov var2, 200

    push var2
    push var1
    pop var2
    pop var1

    print str$(var1),13,10
    print str$(var2),13,10

  ; ------------------------

    mov var1, 100
    mov var2, 200

    mov eax, var1
    mov ecx, var2
    mov var2, eax
    mov var1, ecx

    print str$(var1),13,10
    print str$(var2),13,10

  ; ------------------------

    mov esi, 100
    mov edi, 200

    push esi
    push edi
    pop esi
    pop edi

    print str$(esi),13,10
    print str$(edi),13,10

  ; ------------------------

    mov esi, 100
    mov edi, 200

    mov ebx, esi
    mov esi, edi
    mov edi, ebx

    print str$(esi),13,10
    print str$(edi),13,10

  ; ------------------------

    pop edi
    pop esi
    pop ebx

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start

RedSkeleton007

Quote from: Tedd on July 14, 2015, 01:35:47 AM
XCHG AX,BX copies the value of AX into BX, and the value of BX (before AX was copied there) into AX -- exchanging the values of the two operands in a single instruction.
So given:

mov esi,100
mov edi,200

You're saying that:

mov ebx,esi ;ebx = 100, leaving esi empty
mov esi,edi ;esi now being refilled with 200, leaving edi empty
mov edi,ebx ;moving 100 from ebx back into edi

Is the same as:

xchg esi,edi

If so, does it matter whether I write it as "xchg esi,edi" or "xchg edi,esi"?

dedndave

XCHG ESI,EDI and XCHG EDI,ESI perform the exact same operation
however, they are slightly different opcodes   :P

there is a major difference when one of the registers is EAX
that's because intel gives special encoding for XCHG EAX,reg32

all the other reg-reg exchanges are 2 byte opcodes
but, XCHG EAX,EDX (for example) is a single byte

so - most assemblers will encode XCHG EDX,EAX as XCHG EAX,EDX because it is one byte smaller
but - they perform the same operation

hutch--

Quote
mov ebx,esi ;ebx = 100, leaving esi empty
mov esi,edi ;esi now being refilled with 200, leaving edi empty
mov edi,ebx ;moving 100 from ebx back into edi

Your commenting is incorrect, the MOV mnemonic does not empty the source register. MOV EAX, EDX means move the content of EDX to EAX.

Tedd

Quote from: RedSkeleton007 on July 14, 2015, 06:48:23 AM
So given:

mov esi,100
mov edi,200

You're saying that:

mov ebx,esi ;ebx = 100, leaving esi empty
mov esi,edi ;esi now being refilled with 200, leaving edi empty
mov edi,ebx ;moving 100 from ebx back into edi

Is the same as:

xchg esi,edi

If so, does it matter whether I write it as "xchg esi,edi" or "xchg edi,esi"?
Correct (though registers don't 'empty' they retain their current value unless it is overwritten.)
Equally "xchg esi,edi; xchg esi,edi" does 'nothing,' as do "xchg esi,edi; xchg edi,esi" and "xchg edi,esi; xchg esi,edi" and "xchg edi,esi; xchg edi,esi".
Potato2