Question

Well, I've read the questions that are similar to mine but I haven't been able to solve this problem yet. I've also checked this which could, obviously, solve my problem. But it didn't.

I have a C function in the file I'm working on:

void copiarMuestreo(unsigned short * source, int * sPos, unsigned short * destination, int * dPos, int bitsPerSample ) {...}

All its internal operations are done in C. source is a pointer to a vector, as is destination.

I'm trying to call this function from inline assembly code (I'll put the whole function here):

void unirArchivosWAVE( unsigned short *parte1, unsigned short *parte2, unsigned short *salida, int bitsPorMuestreo ){
int posParte1;                                                                                                  //Posicion en la que lee la primera muestra
int posParte2;                                                                                                  //Posicion en la que lee la segunda muestra
int posSalida;                                                                                                  //Posicion en la que escribe las muestras
int i = pistaEntrada1.numSamples;

__asm {
    push eax
    push ebx
    push ecx
    push edx
    push edi
    mov edi, i
    mov i, 0
    mov posParte1, 0
    mov posParte2, 0
    mov salida, 0
    forGrande:
      cmp i, edi
      jge finForGrande

      lea bx, posParte1
      lea cx, posParte2
      lea dx, posSalida

      push bitsPorMuestreo
      push dx
      push salida
      push bx
      push parte1
      call copiarMuestreo
      pop parte1
      pop bx
      pop salida
      pop dx
      pop bitsPorMuestreo

      push bitsPorMuestreo
      push dx
      push salida
      push cx
      push parte2
      call copiarMuestreo
      pop parte2
      pop cx
      pop salida
      pop dx
      pop bitsPorMuestreo

      inc i
      jmp forGrande
    finForGrande:
    fin:
      pop edi
      pop edx
      pop ecx
      pop ebx
      pop eax
    }
}

I'm programming in Windows 8, 64 bit, with VS2012 Express, in an Intel Core i5. The program crashes beautifully without any sort of error message anywhere, and I suspect it is a segfault. But why?

At first I was pushing the 32-bit registers before calling, and I thought that them being 4 bytes instead of the 2 bytes used by shorts was the problem. Nope, it still crashes.

I'm clueless. I haven't tried anything else because well, I simply don't know what to try. I'm new to assembly.

Sorry for the Spanish variable names.

Was it helpful?

Solution

Using 16 bit registers for the address parameters is definitely not going to work. It's only going to use half the address so whenever those pointers gets dereferenced they could be anywhere.

All of these:

  lea bx, posParte1
  lea cx, posParte2
  lea dx, posSalida

should be:

  lea ebx, posParte1
  lea ecx, posParte2
  lea edx, posSalida

And obviously the push ops below should use the 32 bit registers too.

Update:

Just noticed something else. You are setting your salida parameter to NULL, when assumedly you wanted to set posSalida to zero. This line:

mov salida, 0

should probably have been:

mov posSalida, 0

Update 2:

Also worth mentioning that the ecx register is not guaranteed to be preserved across function calls. So it's quite possible that by the time you return from the first call to copiarMuestreo, the ecx that you set to the address of posParte2 is no longer correct.

Probably the best solution to that would be to initialise ecx only after the first call to copiarMuestreo, since it's not needed until the second call.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top