从内联汇编VS2012调用C函数 - segfault?

时间:2013-05-12 00:34:50

标签: c visual-studio assembly visual-studio-2012 inline-assembly

好吧,我已经阅读了与我类似的问题,但我还没有解决这个问题。我还检查了this,这显然可以解决我的问题。但它没有。

我正在处理的文件中有一个C函数:

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

所有内部操作都在C中完成。 source 是一个指向矢量的指针, destination 也是如此。

我正在尝试从内联汇编代码调用此函数(我将把整个函数放在这里):

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
    }
}

我使用英特尔酷睿i5在Windows 8,64位,使用VS2012 Express进行编程。该程序在任何地方都没有任何错误消息,崩溃得很漂亮,我怀疑这是一个段错误。但为什么呢?

起初我在调用之前推动了32位寄存器,我认为它们是4个字节而不是短路使用的2个字节是问题所在。不,它仍然崩溃。

我很无能为力。我没有尝试过其他任何事情,因为我只是不知道该尝试什么。我是集会的新手。

对不起西班牙语变量名称。

1 个答案:

答案 0 :(得分:2)

使用16位寄存器作为地址参数肯定不会起作用。它只会使用一半的地址,因此每当这些指针被取消引用时,它们就可以在任何地方。

所有这些:

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

应该是:

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

显然下面的push操作也应该使用32位寄存器。

<强>更新

刚注意到别的东西。您假设要将salida设置为零,则将posSalida参数设置为NULL。这一行:

mov salida, 0

应该是:

mov posSalida, 0

更新2:

另外值得一提的是,ecx寄存器不能保证在函数调用中保留。因此,当您从第一次调用返回copiarMuestreo时,您设置为posParte2地址的ecx不再正确。

可能最好的解决方案是在第一次拨打copiarMuestreo后初始化ecx,因为在第二次通话之前不需要它。