2

Ну, я прочитал вопросы, похожие на мои, но я еще не смог решить эту проблему. Я также проверил this, что, очевидно, может решить мою проблему. Но это не так.Функция вызова C из встроенной сборки VS2012 - segfault?

У меня есть функция C в файле я работаю:

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

Все его внутренние операции выполняются в C. источника указатель на вектор, как назначения.

Я пытаюсь вызвать эту функцию из встроенного кода сборки (я положу всю функцию здесь):

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

Я программирование в Windows 8, 64 бит, с VS2012 Express, в Intel Core i5. Программа прекращается без каких-либо сообщений об ошибках в любом месте, и я подозреваю, что это segfault. Но почему?

Сначала я нажимал 32-разрядные регистры перед вызовом, и я думал, что проблема была в 4 байтах вместо 2 байтов, используемых шортами. Нет, он все еще падает.

Я не знаю. Я ничего не пробовал, потому что хорошо, я просто не знаю, что попробовать. Я новичок в сборке.

Извините за имена переменных в Испании.

+0

Вы можете запустить его через отладчик? – FDinoff

+0

Я не знаю, как, как это встроенный код. Отладчик VS дает мне ошибки относительно некоторых файлов PDB, которые недоступны. –

ответ

2

Использование 16-разрядных регистров для параметров адреса, безусловно, не сработает. Он будет использовать только половину адреса, поэтому, когда эти указатели будут разыменованы, они могут быть где угодно.

Все эти:

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

должно быть:

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

И очевидно, push ОПС ниже следует использовать 32-битные регистры тоже.

Update:

Просто заметил что-то другое. Вы устанавливаете свой salida параметр NULL, когда предположительно вы хотите установить posSalida на ноль. Эта линия:

mov salida, 0 

, вероятно, были:

mov posSalida, 0 

Update 2:

Также стоит отметить, что регистр ECX не гарантируется сохраняется между вызовами функций. Поэтому вполне возможно, что к моменту возврата с первого звонка до copiarMuestreo, ecx, который вы указали по адресу posParte2, больше не верна.

Возможно, лучшим решением для этого было бы инициализировать ecx только после первого вызова copiarMuestreo, так как он не нужен до второго вызова.

+0

Да, все это было неправильно. Некоторое время я не проверял вопрос и должен был их обнаружить, когда я, наконец, сделал работу отладчика. Благодарю. –

+0

Можно ли сохранить регистры YMM XMM по всем функциям? –

+0

@huseyintugrulbuyukisik Я не уверен, но я думаю, что некоторые из них сохранились, а некоторые нет. Вероятно, это также зависит от того, является ли это 64-разрядным приложением или 32-разрядным приложением (у них разные соглашения о вызовах). Вероятно, вы сможете получить лучший ответ от кого-то более осведомленного на эту тему, если вы представите это как новый вопрос. –

Смежные вопросы