I have ASM code of some Windows *.exe in IDA:

mov     rax, [rbx+10h]
mov     ecx, edx
xor     edx, edx
xchg    rdx, [rax+rcx*8]

Which is decompiled to pseudocode to

_RAX = this->m_someMemoryPool;
_RCX = v4;
_RDX = 0i64;
__asm { xchg    rdx, [rax+rcx*8] }

If there won't be any memory barries, code would look like this

void* _RDX = m_someMemoryPool[v4];

But I'm wondering, what does xchg means here. Is it equivalent to

void* _RDX = NULL;
InterlockedExchange(&_RDX, m_someMemoryPool[v4]);

? Or there is more complicated synchronization construction should be used?

  • 2
    Are you are talking about the Microsoft Windows InterlockedExchange function which sets a variable to the specified value as an atomic operation? If so, then yes it is functionally equivalent. The XCHG instruction is implicitly bus-locked regardless of the absence of a LOCK prefix because of the access to a memory location. – fpmurphy Sep 1 '20 at 16:41

here is the sample code that will show both the constructs if there is an atomic exchange requirement you use the api or intrinsc provided else simply assign


#include <stdio.h>
#include <windows.h>
#include <intrin.h>

long tmp[10] = {NULL};
long *m_someMemoryPool[10] ={NULL};

int main (void) {
    tmp[0] = 0xbee5deed;
    long foo =0xbee5dead;
    m_someMemoryPool[0] = &tmp[0];
    printf("%p = %x\n" , m_someMemoryPool[0] , *(int *)(m_someMemoryPool[0]));
    _InterlockedExchange( m_someMemoryPool[0], foo);
    printf("%p = %x\n" , m_someMemoryPool[0] , *(int *)(m_someMemoryPool[0]));

compiled with vs2017 community as x86 with

cl /Zi /W4 /O1 /EHsc /analyze /nologo xchg.cpp /link /release


013499D0 = bee5deed
013499D0 = bee5dead


cdb -c "uf xchg!main;q" xchg.exe | awk "/Reading/,/quit/"
0:000> cdb: Reading initial command 'uf xchg!main;q'
01301029 56              push    esi
0130102a b9eddee5be      mov     ecx,0BEE5DEEDh    <<<<<<<<<<<<<<<<
0130102f b8d0993401      mov     eax,offset xchg!tmp (013499d0)
01301034 51              push    ecx
01301035 50              push    eax
01301036 be90013401      mov     esi,offset xchg!`string' (01340190)
0130103b 890dd0993401    mov     dword ptr [xchg!tmp (013499d0)],ecx
01301041 56              push    esi
01301042 a3f8993401      mov     dword ptr [xchg!m_someMemoryPool (013499f8)],eax
01301047 e821000000      call    xchg!printf (0130106d)
0130104c a1f8993401      mov     eax,dword ptr [xchg!m_someMemoryPool (013499f8)]
01301051 b9addee5be      mov     ecx,0BEE5DEADh
01301056 8708            xchg    ecx,dword ptr [eax]  <<<<<<<<<<<<<
01301058 a1f8993401      mov     eax,dword ptr [xchg!m_someMemoryPool (013499f8)]
0130105d ff30            push    dword ptr [eax]
0130105f 50              push    eax
01301060 56              push    esi
01301061 e807000000      call    xchg!printf (0130106d)
01301066 83c418          add     esp,18h
01301069 33c0            xor     eax,eax
0130106b 5e              pop     esi
0130106c c3              ret

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.