views:

209

answers:

3

I've written an assembler function to speed up a few things for image processing (images are created with CreateDIBSection).

For Win32 the assembler code works without problems, but for Win64 I get a crash as soon as I try to access my array data.

I put the relevant info in a struct and my assembler function gets a pointer to this struct. The struct pointer is put into ebx/rbx and with indexing I read the data from the struct.

Any idea what I am doing wrong? I use nasm together with Visual Studio 2008 and for Win64 I set "default rel".

C++ code:

struct myData {
  tUInt32 ulParam1;
  void* pData;
};

CallMyAssemblerFunction(&myData);

Assembler Code:

Win32:

...
  push ebp;
  mov ebp,esp
  mov ebx, [ebp + 8]; pointer to our struct
  mov eax, [ebx]; ulParam1
  mov esi, [ebx + 4]; pData, 4 byte pointer

  movd xmm0, [esi];
...

Win64:

...
  mov rbx, rcx; pointer to our struct
  mov eax, [rbx]; ulParam1
  mov rsi, [rbx + 4]; pData, 8 byte pointer

  movd xmm0, [rsi]; CRASH!
...
+3  A: 

8-byte structure alignment issue?

Giuseppe Guerrini
+2  A: 

Take a look at your struncture in memory. May be offset is different in x64

Andrey
+7  A: 

Quite probably, the pData field is at [rbx + 8], not [rbx + 4]. The compiler inserts some extra space ("padding") between ulParam1 and pData so that pData is 8-byte aligned (which makes accesses faster).

Thomas Pornin
You can easily check this by either printing sizeof(myData) or looking at the addresses on the C++ side in a debugger.
Mark B
Thanks a lot - it was indeed an alignment issue. The pData field begins at [rbx + 8]. Now everything is working.